diff --git a/.github/workflows/check_release_notes.yml b/.github/workflows/check_release_notes.yml new file mode 100644 index 00000000000..5145e00eb7a --- /dev/null +++ b/.github/workflows/check_release_notes.yml @@ -0,0 +1,19 @@ +# This workflow will perform the following checks: +# 1. Check the PR for a specific label (by default 'release-note-required'); if it's not there, exit +# 2. Check the PR body for a matching release-note code block; if missing, fail +# 3. Check the contents of the code block to ensure it's not empty or 'TBD'; otherwise, fail +# 4. Success! + +name: Validate Release Notes +on: + pull_request: + types: [labeled, unlabeled, edited, synchronize, ready_for_review] +jobs: + label: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - name: Validate Release Notes + uses: tigera/check-release-notes@main diff --git a/.gitignore b/.gitignore index af7b239ef9e..d0fde04b7d0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,14 +11,13 @@ postrelease-checks.xml crypto/tmp /* Produced as part of release */ -hack/release/release +release/release node/windows-packaging/CalicoWindows/confd/config-bgp.ps1 node/windows-packaging/CalicoWindows/confd/config-bgp.psm1 node/windows-packaging/nssm.zip node/windows-packaging/nssm.exe _output builder.coverprofile -hack/release/ghr /* Created by local kind cluster */ hack/test/kind/kind diff --git a/.semaphore/.gitattributes b/.semaphore/.gitattributes new file mode 100644 index 00000000000..2145d51400f --- /dev/null +++ b/.semaphore/.gitattributes @@ -0,0 +1,2 @@ +semaphore.yml linguist-generated=true +semaphore-scheduled-builds.yml linguist-generated=true diff --git a/.semaphore/cleanup.yml b/.semaphore/cleanup.yml index bdb784c690c..5019a5d62da 100644 --- a/.semaphore/cleanup.yml +++ b/.semaphore/cleanup.yml @@ -2,7 +2,7 @@ version: v1.0 name: Felix agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -27,3 +27,21 @@ blocks: - ./.semaphore/clean-up-vms ${VM_PREFIX} secrets: - name: google-service-account-for-gce + +- name: Clean up windows resources + dependencies: [] + task: + prologue: + commands: + - checkout + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none + - cd process/testing/util + jobs: + - name: Clean up windows felix resources + commands: + - ./delete-az-rg.sh ${USER}-capz-win-felix-${SEMAPHORE_WORKFLOW_ID:0:8}-rg + - name: Clean up windows cni resources + commands: + - ./delete-az-rg.sh ${USER}-capz-win-cni-${SEMAPHORE_WORKFLOW_ID:0:8}-rg + secrets: + - name: banzai-secrets diff --git a/.semaphore/license-scanning/fossa-scan.yml b/.semaphore/license-scanning/fossa-scan.yml index f07b4847b09..58aa703d283 100644 --- a/.semaphore/license-scanning/fossa-scan.yml +++ b/.semaphore/license-scanning/fossa-scan.yml @@ -3,7 +3,7 @@ name: Run Fossa Scan agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: diff --git a/.semaphore/push-images/alp.yml b/.semaphore/push-images/alp.yml index 32f1df8145b..5d0d9ab4360 100644 --- a/.semaphore/push-images/alp.yml +++ b/.semaphore/push-images/alp.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish ALP images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/apiserver.yml b/.semaphore/push-images/apiserver.yml index 6e334344495..03fb3137cb1 100644 --- a/.semaphore/push-images/apiserver.yml +++ b/.semaphore/push-images/apiserver.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish apiserver images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/calicoctl.yml b/.semaphore/push-images/calicoctl.yml index 337a26b48be..1ce228cf0bc 100644 --- a/.semaphore/push-images/calicoctl.yml +++ b/.semaphore/push-images/calicoctl.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish calicoctl images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/cni-plugin.yml b/.semaphore/push-images/cni-plugin.yml index 781af3a1498..0a0a5ba61a9 100644 --- a/.semaphore/push-images/cni-plugin.yml +++ b/.semaphore/push-images/cni-plugin.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish cni-plugin images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/key-cert-provisioner.yml b/.semaphore/push-images/key-cert-provisioner.yml index f2796ba33ef..92d082cb052 100644 --- a/.semaphore/push-images/key-cert-provisioner.yml +++ b/.semaphore/push-images/key-cert-provisioner.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish key-cert-provisioner images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/kube-controllers.yml b/.semaphore/push-images/kube-controllers.yml index c8155104f0f..5cb0428aa66 100644 --- a/.semaphore/push-images/kube-controllers.yml +++ b/.semaphore/push-images/kube-controllers.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish kube-controllers images agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/node.yml b/.semaphore/push-images/node.yml index f60e71ac539..dc1d3c8ba6e 100644 --- a/.semaphore/push-images/node.yml +++ b/.semaphore/push-images/node.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish node images agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/packaging.yaml b/.semaphore/push-images/packaging.yaml index 793ebae28a0..553fbb7a657 100644 --- a/.semaphore/push-images/packaging.yaml +++ b/.semaphore/push-images/packaging.yaml @@ -2,7 +2,7 @@ version: v1.0 name: Publish openstack packages agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -46,4 +46,4 @@ blocks: jobs: - name: "packages" commands: - - if [ -z "${SEMAPHORE_GIT_PR_NUMBER}" ]; then make -C hack/release/packaging release-publish VERSION=$SEMAPHORE_GIT_BRANCH; fi + - if [ -z "${SEMAPHORE_GIT_PR_NUMBER}" ]; then make -C release/packaging release-publish VERSION=$SEMAPHORE_GIT_BRANCH; fi diff --git a/.semaphore/push-images/pod2daemon.yml b/.semaphore/push-images/pod2daemon.yml index 963749f8ce6..90fdf1da20c 100644 --- a/.semaphore/push-images/pod2daemon.yml +++ b/.semaphore/push-images/pod2daemon.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish pod2daemon images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/push-images/typha.yml b/.semaphore/push-images/typha.yml index f86d238dc9b..f824a02a7b6 100644 --- a/.semaphore/push-images/typha.yml +++ b/.semaphore/push-images/typha.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish typha images agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -24,8 +24,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} # Semaphore is doing shallow clone on a commit without tags. # unshallow it for GIT_VERSION:=$(shell git describe --tags --dirty --always) - retry git fetch --unshallow diff --git a/.semaphore/release/hashrelease.yml b/.semaphore/release/hashrelease.yml new file mode 100644 index 00000000000..e97f8fed6c7 --- /dev/null +++ b/.semaphore/release/hashrelease.yml @@ -0,0 +1,54 @@ +version: v1.0 +name: Publish hashrelease +agent: + machine: + type: f1-standard-2 + os_image: ubuntu2004 +execution_time_limit: + hours: 4 + +global_job_config: + secrets: + # Github SSH secret for pulling private repositories. + - name: private-repo + # Secret for GitHub API access. + - name: marvin-github-token + # Secret for pushing to the docs box. + - name: docs-ssh + # Secret for pulling images from GCR. + - name: gcloud-registry-access + # Secret for the docker auth + - name: hashrelease-docker-auth + # Secret for Image Scanning Service + - name: iss-image-scanning + # Secrets for Slack notifications + - name: releasebot-slack + prologue: + commands: + - chmod 0600 ~/.keys/* + - ssh-add ~/.keys/* + - export GOOGLE_APPLICATION_CREDENTIALS=${HOME}/keys/.registry-viewer-serviceaccount.json + - gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} + - docker login + - checkout + # Unshallow the git repository to get latest tags + - retry git fetch --quiet --unshallow + +blocks: + - name: Publish hashrelease + task: + jobs: + - name: Build and publish hashrelease + commands: + - ./bin/release hashrelease build + - ./bin/release hashrelease publish + prologue: + commands: + - export GITHUB_TOKEN=${MARVIN_GITHUB_TOKEN} + - cd release + - make build + env_vars: + - name: OPERATOR_BRANCH + value: master + - name: IS_HASHRELEASE + value: "true" diff --git a/.semaphore/release/release.yml b/.semaphore/release/release.yml index b4681090a2d..8f110066914 100644 --- a/.semaphore/release/release.yml +++ b/.semaphore/release/release.yml @@ -2,7 +2,7 @@ version: v1.0 name: Publish official release agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 execution_time_limit: @@ -46,8 +46,6 @@ blocks: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/.kiex ~/.phpbrew ~/.rbenv ~/.nvm ~/.kerl ~/.sbt ~/.npm /usr/lib/jvm /opt/firefox* /opt/apache-maven* /opt/scala /usr/local/golang # Log in to container registries needed for release. - echo $DOCKER_TOKEN | docker login --username "$DOCKER_USER" --password-stdin - echo $QUAY_TOKEN | docker login --username "$QUAY_USER" --password-stdin quay.io @@ -87,8 +85,6 @@ blocks: - ssh-add /home/semaphore/.keys/git_ssh_rsa # Checkout the code and unshallow it. - checkout - # Free up space on the build machine. - - sudo rm -rf ~/.kiex ~/.phpbrew ~/.rbenv ~/.nvm ~/.kerl ~/.sbt ~/.npm /usr/lib/jvm /opt/firefox* /opt/apache-maven* /opt/scala /usr/local/golang # Install more tools - sudo apt update - sudo apt install -y moreutils patchelf @@ -108,5 +104,5 @@ blocks: epilogue: always: commands: - - test -d hack/release/packaging/output && mv -v hack/release/packaging/output hack/release/packaging/openstack - - artifact push workflow hack/release/packaging/openstack + - test -d release/packaging/output && mv -v release/packaging/output release/packaging/openstack + - artifact push workflow release/packaging/openstack diff --git a/.semaphore/rerun_failed_jobs.yml b/.semaphore/rerun_failed_jobs.yml new file mode 100644 index 00000000000..9a8df5f076c --- /dev/null +++ b/.semaphore/rerun_failed_jobs.yml @@ -0,0 +1,24 @@ +version: v1.0 +name: Rerun failed jobs +agent: + machine: + type: f1-standard-2 + os_image: ubuntu2204 + +execution_time_limit: + minutes: 10 + +blocks: + - name: Rerun failed jobs + dependencies: [] + task: + secrets: + - name: semaphore-api + jobs: + - name: Rerun failed jobs + commands: + - curl https://storage.googleapis.com/sem-cli-releases/get.sh | bash + - export CONNECT_URL=${SEMAPHORE_ORGANIZATION_URL#"https://"} + - /usr/local/bin/sem connect $CONNECT_URL $SEMAPHORE_API_TOKEN + - export PIPELINE=$(/usr/local/bin/sem get workflows $SEMAPHORE_WORKFLOW_ID -i $SEMAPHORE_PROJECT_ID | tail -n 1 | awk '{print $1}') + - /usr/local/bin/sem rebuild pipeline $PIPELINE diff --git a/.semaphore/semaphore-scheduled-builds.yml b/.semaphore/semaphore-scheduled-builds.yml index ad26f91174f..4952e866d54 100644 --- a/.semaphore/semaphore-scheduled-builds.yml +++ b/.semaphore/semaphore-scheduled-builds.yml @@ -6,7 +6,7 @@ execution_time_limit: hours: 4 agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 auto_cancel: running: @@ -30,8 +30,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} - echo $DOCKERHUB_PASSWORD | docker login --username "$DOCKERHUB_USERNAME" --password-stdin # Disable initramfs update to save space on the Semaphore VM (and we don't need it because we're not going to reboot). - sudo apt-get install -y -u crudini @@ -42,6 +40,9 @@ global_job_config: - cd "$REPO_DIR" - .semaphore/publish-artifacts promotions: + # Manual promotion for publishing a hashrelease. + - name: Publish hashrelease + pipeline_file: release/hashrelease.yml # Manual promotion for publishing a release. - name: Publish official release pipeline_file: release/release.yml @@ -50,6 +51,9 @@ promotions: pipeline_file: cleanup.yml auto_promote: when: "result = 'stopped'" + # Rerun failed jobs + - name: Rerun failed jobs + pipeline_file: rerun_failed_jobs.yml # Have separate promotions for publishing images so we can re-run # them individually if they fail, and so we can run them in parallel. - name: Push apiserver images @@ -116,7 +120,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -199,15 +203,16 @@ blocks: - cni-plugin task: secrets: - - name: azure-dev-ci + - name: banzai-secrets prologue: commands: # Prepare azure configuration. - - az login --service-principal -u "${AZ_USER}" -p "${AZ_PASS}" --tenant "${AZ_TENANT}" --output none + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none - export AZURE_SUBSCRIPTION_ID=$AZ_SUBSCRIPTION_ID - - export AZURE_TENANT_ID=$AZ_TENANT - - export AZURE_CLIENT_ID=$AZ_USER - - export AZURE_CLIENT_SECRET=$AZ_PASS + - export AZURE_TENANT_ID=$AZ_TENANT_ID + - export AZURE_CLIENT_ID=$AZ_SP_ID + - export AZURE_CLIENT_SECRET=$AZ_SP_PASSWORD + - export AZURE_RESOURCE_GROUP=${USER}-capz-win-cni-${SEMAPHORE_WORKFLOW_ID:0:8}-rg - export REPORT_DIR=/home/semaphore/calico/process/testing/winfv-cni-plugin/report - export LOGS_DIR=~/fv.log - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) @@ -227,7 +232,7 @@ blocks: - name: AZURE_LOCATION value: eastus2 - name: KUBE_VERSION - value: v1.29.4 + value: v1.29.7 jobs: - name: Containerd - Windows FV execution_time_limit: @@ -270,7 +275,7 @@ blocks: task: agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 jobs: - name: sig-network conformance @@ -281,13 +286,13 @@ blocks: - .semaphore/run-and-monitor e2e-test.log make e2e-test - name: "Felix: Build" run: - when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/hack/test/certs/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/hack/test/certs/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - Prerequisites task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -337,8 +342,9 @@ blocks: - s390x commands: # Only building the code, not the image here because the felix image is now only used for FV tests, which - # only run on AMD64 at the moment. - - ../.semaphore/run-and-monitor build-$ARCH.log make build ARCH=$ARCH + # only run on AMD64 at the moment. Skip building protofbufs because the build fails on ARM due to missing + # image. We know they are up-to-date because an earlier build job checks already. + - ../.semaphore/run-and-monitor build-$ARCH.log make build ARCH=$ARCH SKIP_PROTOBUF=true - name: "Felix: Build - native arm64 runner" run: @@ -373,7 +379,7 @@ blocks: - name: "Felix: Windows FV capz" run: - when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/node', '/hack/test/certs/', '/process/testing/winfv/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/node', '/hack/test/certs/', '/process/testing/winfv-felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: ["Felix: Build Windows binaries"] task: secrets: @@ -381,7 +387,8 @@ blocks: - name: private-repo prologue: commands: - - export REPORT_DIR=/home/semaphore/calico/process/testing/winfv/report + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none + - export REPORT_DIR=/home/semaphore/report - export AZURE_SUBSCRIPTION_ID=$AZ_SUBSCRIPTION_ID - export AZURE_TENANT_ID=$AZ_TENANT_ID - export AZURE_CLIENT_ID=$AZ_SP_ID @@ -409,7 +416,7 @@ blocks: - name: "Felix: FV Tests" run: - when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - "Felix: Build" task: @@ -475,7 +482,40 @@ blocks: - name: "Felix: BPF UT/FV tests on new kernel" run: - when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + dependencies: + - Prerequisites + task: + prologue: + commands: + - cd felix + - export GOOGLE_APPLICATION_CREDENTIALS=$HOME/secrets/secret.google-service-account-key.json + - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) + - export ZONE=europe-west3-c + - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix-ipt- + - echo VM_PREFIX=${VM_PREFIX} + - export REPO_NAME=$(basename $(pwd)) + - export NUM_FV_BATCHES=8 + - mkdir artifacts + - ./.semaphore/create-test-vms ${VM_PREFIX} + jobs: + - name: UT/FV tests on new kernel + execution_time_limit: + minutes: 180 + commands: + - ./.semaphore/run-tests-on-vms ${VM_PREFIX} + epilogue: + always: + commands: + - ./.semaphore/collect-artifacts-from-vms ${VM_PREFIX} + - ./.semaphore/publish-artifacts + - ./.semaphore/clean-up-vms ${VM_PREFIX} + secrets: + - name: google-service-account-for-gce + +- name: "Felix: BPF UT/FV tests on new kernel (nftables)" + run: + when: "true or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - Prerequisites task: @@ -485,7 +525,7 @@ blocks: - export GOOGLE_APPLICATION_CREDENTIALS=$HOME/secrets/secret.google-service-account-key.json - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) - export ZONE=europe-west3-c - - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix- + - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix-nft- - echo VM_PREFIX=${VM_PREFIX} - export REPO_NAME=$(basename $(pwd)) - export NUM_FV_BATCHES=8 @@ -493,6 +533,9 @@ blocks: - ./.semaphore/create-test-vms ${VM_PREFIX} jobs: - name: UT/FV tests on new kernel + env_vars: + - name: FELIX_FV_NFTABLES + value: "Enabled" execution_time_limit: minutes: 180 commands: @@ -513,7 +556,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -543,7 +586,7 @@ blocks: task: agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 prologue: commands: @@ -561,7 +604,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -652,7 +695,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -685,7 +728,7 @@ blocks: task: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -702,7 +745,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -730,6 +773,25 @@ blocks: - mkdir logs - sudo journalctl > logs/journalctl.txt - artifact push job --expire-in 1d logs +- name: release + run: + when: "true or change_in(['/*', '/release/'], {exclude: ['/**/.gitignore', '/**/*.md', '/**/LICENSE']})" + execution_time_limit: + minutes: 30 + dependencies: + - Prerequisites + task: + prologue: + commands: + - cd release + jobs: + - name: make ci + commands: + - ../.semaphore/run-and-monitor release-ci.log make ci + - name: Build binary + commands: + - ../.semaphore/run-and-monitor release-build.log make build + - cache store release-${SEMAPHORE_GIT_SHA} bin after_pipeline: task: jobs: diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index e47aeb0a7cc..57f5b2516b2 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -6,7 +6,7 @@ execution_time_limit: hours: 4 agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 auto_cancel: running: @@ -30,8 +30,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} - echo $DOCKERHUB_PASSWORD | docker login --username "$DOCKERHUB_USERNAME" --password-stdin # Disable initramfs update to save space on the Semaphore VM (and we don't need it because we're not going to reboot). - sudo apt-get install -y -u crudini @@ -42,6 +40,9 @@ global_job_config: - cd "$REPO_DIR" - .semaphore/publish-artifacts promotions: + # Manual promotion for publishing a hashrelease. + - name: Publish hashrelease + pipeline_file: release/hashrelease.yml # Manual promotion for publishing a release. - name: Publish official release pipeline_file: release/release.yml @@ -50,6 +51,9 @@ promotions: pipeline_file: cleanup.yml auto_promote: when: "result = 'stopped'" + # Rerun failed jobs + - name: Rerun failed jobs + pipeline_file: rerun_failed_jobs.yml # Have separate promotions for publishing images so we can re-run # them individually if they fail, and so we can run them in parallel. - name: Push apiserver images @@ -116,7 +120,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -199,15 +203,16 @@ blocks: - cni-plugin task: secrets: - - name: azure-dev-ci + - name: banzai-secrets prologue: commands: # Prepare azure configuration. - - az login --service-principal -u "${AZ_USER}" -p "${AZ_PASS}" --tenant "${AZ_TENANT}" --output none + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none - export AZURE_SUBSCRIPTION_ID=$AZ_SUBSCRIPTION_ID - - export AZURE_TENANT_ID=$AZ_TENANT - - export AZURE_CLIENT_ID=$AZ_USER - - export AZURE_CLIENT_SECRET=$AZ_PASS + - export AZURE_TENANT_ID=$AZ_TENANT_ID + - export AZURE_CLIENT_ID=$AZ_SP_ID + - export AZURE_CLIENT_SECRET=$AZ_SP_PASSWORD + - export AZURE_RESOURCE_GROUP=${USER}-capz-win-cni-${SEMAPHORE_WORKFLOW_ID:0:8}-rg - export REPORT_DIR=/home/semaphore/calico/process/testing/winfv-cni-plugin/report - export LOGS_DIR=~/fv.log - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) @@ -227,7 +232,7 @@ blocks: - name: AZURE_LOCATION value: eastus2 - name: KUBE_VERSION - value: v1.29.4 + value: v1.29.7 jobs: - name: Containerd - Windows FV execution_time_limit: @@ -270,7 +275,7 @@ blocks: task: agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 jobs: - name: sig-network conformance @@ -281,13 +286,13 @@ blocks: - .semaphore/run-and-monitor e2e-test.log make e2e-test - name: "Felix: Build" run: - when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/hack/test/certs/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/hack/test/certs/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - Prerequisites task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -337,8 +342,9 @@ blocks: - s390x commands: # Only building the code, not the image here because the felix image is now only used for FV tests, which - # only run on AMD64 at the moment. - - ../.semaphore/run-and-monitor build-$ARCH.log make build ARCH=$ARCH + # only run on AMD64 at the moment. Skip building protofbufs because the build fails on ARM due to missing + # image. We know they are up-to-date because an earlier build job checks already. + - ../.semaphore/run-and-monitor build-$ARCH.log make build ARCH=$ARCH SKIP_PROTOBUF=true - name: "Felix: Build - native arm64 runner" run: @@ -373,7 +379,7 @@ blocks: - name: "Felix: Windows FV capz" run: - when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/node', '/hack/test/certs/', '/process/testing/winfv/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/node', '/hack/test/certs/', '/process/testing/winfv-felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: ["Felix: Build Windows binaries"] task: secrets: @@ -381,7 +387,8 @@ blocks: - name: private-repo prologue: commands: - - export REPORT_DIR=/home/semaphore/calico/process/testing/winfv/report + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none + - export REPORT_DIR=/home/semaphore/report - export AZURE_SUBSCRIPTION_ID=$AZ_SUBSCRIPTION_ID - export AZURE_TENANT_ID=$AZ_TENANT_ID - export AZURE_CLIENT_ID=$AZ_SP_ID @@ -409,7 +416,7 @@ blocks: - name: "Felix: FV Tests" run: - when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - "Felix: Build" task: @@ -475,7 +482,40 @@ blocks: - name: "Felix: BPF UT/FV tests on new kernel" run: - when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + dependencies: + - Prerequisites + task: + prologue: + commands: + - cd felix + - export GOOGLE_APPLICATION_CREDENTIALS=$HOME/secrets/secret.google-service-account-key.json + - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) + - export ZONE=europe-west3-c + - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix-ipt- + - echo VM_PREFIX=${VM_PREFIX} + - export REPO_NAME=$(basename $(pwd)) + - export NUM_FV_BATCHES=8 + - mkdir artifacts + - ./.semaphore/create-test-vms ${VM_PREFIX} + jobs: + - name: UT/FV tests on new kernel + execution_time_limit: + minutes: 180 + commands: + - ./.semaphore/run-tests-on-vms ${VM_PREFIX} + epilogue: + always: + commands: + - ./.semaphore/collect-artifacts-from-vms ${VM_PREFIX} + - ./.semaphore/publish-artifacts + - ./.semaphore/clean-up-vms ${VM_PREFIX} + secrets: + - name: google-service-account-for-gce + +- name: "Felix: BPF UT/FV tests on new kernel (nftables)" + run: + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - Prerequisites task: @@ -485,7 +525,7 @@ blocks: - export GOOGLE_APPLICATION_CREDENTIALS=$HOME/secrets/secret.google-service-account-key.json - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) - export ZONE=europe-west3-c - - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix- + - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix-nft- - echo VM_PREFIX=${VM_PREFIX} - export REPO_NAME=$(basename $(pwd)) - export NUM_FV_BATCHES=8 @@ -493,6 +533,9 @@ blocks: - ./.semaphore/create-test-vms ${VM_PREFIX} jobs: - name: UT/FV tests on new kernel + env_vars: + - name: FELIX_FV_NFTABLES + value: "Enabled" execution_time_limit: minutes: 180 commands: @@ -513,7 +556,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -543,7 +586,7 @@ blocks: task: agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 prologue: commands: @@ -561,7 +604,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -652,7 +695,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -685,7 +728,7 @@ blocks: task: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -702,7 +745,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -730,6 +773,25 @@ blocks: - mkdir logs - sudo journalctl > logs/journalctl.txt - artifact push job --expire-in 1d logs +- name: release + run: + when: "false or change_in(['/*', '/release/'], {exclude: ['/**/.gitignore', '/**/*.md', '/**/LICENSE']})" + execution_time_limit: + minutes: 30 + dependencies: + - Prerequisites + task: + prologue: + commands: + - cd release + jobs: + - name: make ci + commands: + - ../.semaphore/run-and-monitor release-ci.log make ci + - name: Build binary + commands: + - ../.semaphore/run-and-monitor release-build.log make build + - cache store release-${SEMAPHORE_GIT_SHA} bin after_pipeline: task: jobs: diff --git a/.semaphore/semaphore.yml.d/01-preamble.yml b/.semaphore/semaphore.yml.d/01-preamble.yml index e4c56a7cf97..69aee7c3d4c 100644 --- a/.semaphore/semaphore.yml.d/01-preamble.yml +++ b/.semaphore/semaphore.yml.d/01-preamble.yml @@ -4,7 +4,7 @@ execution_time_limit: hours: 4 agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 auto_cancel: running: diff --git a/.semaphore/semaphore.yml.d/02-global_job_config.yml b/.semaphore/semaphore.yml.d/02-global_job_config.yml index eb1864e15ce..40d5812b625 100644 --- a/.semaphore/semaphore.yml.d/02-global_job_config.yml +++ b/.semaphore/semaphore.yml.d/02-global_job_config.yml @@ -15,8 +15,6 @@ global_job_config: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/{.kerl,.kiex,.npm,.nvm,.phpbrew,.rbenv,.sbt} /opt/{apache-maven*,firefox*,scala} /usr/lib/jvm /usr/local/{aws2,golang,phantomjs*} - echo $DOCKERHUB_PASSWORD | docker login --username "$DOCKERHUB_USERNAME" --password-stdin # Disable initramfs update to save space on the Semaphore VM (and we don't need it because we're not going to reboot). - sudo apt-get install -y -u crudini diff --git a/.semaphore/semaphore.yml.d/03-promotions.yml b/.semaphore/semaphore.yml.d/03-promotions.yml index 7fc8373a7f4..9a588ee208a 100644 --- a/.semaphore/semaphore.yml.d/03-promotions.yml +++ b/.semaphore/semaphore.yml.d/03-promotions.yml @@ -1,4 +1,7 @@ promotions: + # Manual promotion for publishing a hashrelease. + - name: Publish hashrelease + pipeline_file: release/hashrelease.yml # Manual promotion for publishing a release. - name: Publish official release pipeline_file: release/release.yml @@ -7,6 +10,9 @@ promotions: pipeline_file: cleanup.yml auto_promote: when: "result = 'stopped'" + # Rerun failed jobs + - name: Rerun failed jobs + pipeline_file: rerun_failed_jobs.yml # Have separate promotions for publishing images so we can re-run # them individually if they fail, and so we can run them in parallel. - name: Push apiserver images diff --git a/.semaphore/semaphore.yml.d/blocks/20-apiserver.yml b/.semaphore/semaphore.yml.d/blocks/20-apiserver.yml index 38899f521ef..43e2c6840f0 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-apiserver.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-apiserver.yml @@ -8,7 +8,7 @@ task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: diff --git a/.semaphore/semaphore.yml.d/blocks/20-cni-plugin.yml b/.semaphore/semaphore.yml.d/blocks/20-cni-plugin.yml index ea4c52893c7..0bf7d89e632 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-cni-plugin.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-cni-plugin.yml @@ -22,15 +22,16 @@ - cni-plugin task: secrets: - - name: azure-dev-ci + - name: banzai-secrets prologue: commands: # Prepare azure configuration. - - az login --service-principal -u "${AZ_USER}" -p "${AZ_PASS}" --tenant "${AZ_TENANT}" --output none + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none - export AZURE_SUBSCRIPTION_ID=$AZ_SUBSCRIPTION_ID - - export AZURE_TENANT_ID=$AZ_TENANT - - export AZURE_CLIENT_ID=$AZ_USER - - export AZURE_CLIENT_SECRET=$AZ_PASS + - export AZURE_TENANT_ID=$AZ_TENANT_ID + - export AZURE_CLIENT_ID=$AZ_SP_ID + - export AZURE_CLIENT_SECRET=$AZ_SP_PASSWORD + - export AZURE_RESOURCE_GROUP=${USER}-capz-win-cni-${SEMAPHORE_WORKFLOW_ID:0:8}-rg - export REPORT_DIR=/home/semaphore/calico/process/testing/winfv-cni-plugin/report - export LOGS_DIR=~/fv.log - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) @@ -50,7 +51,7 @@ - name: AZURE_LOCATION value: eastus2 - name: KUBE_VERSION - value: v1.29.4 + value: v1.29.7 jobs: - name: Containerd - Windows FV execution_time_limit: diff --git a/.semaphore/semaphore.yml.d/blocks/20-e2e.yml b/.semaphore/semaphore.yml.d/blocks/20-e2e.yml index a58ee63f2d2..ce75caea859 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-e2e.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-e2e.yml @@ -6,7 +6,7 @@ task: agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 jobs: - name: sig-network conformance diff --git a/.semaphore/semaphore.yml.d/blocks/20-felix.yml b/.semaphore/semaphore.yml.d/blocks/20-felix.yml index 40c224bda3f..0192d394170 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-felix.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-felix.yml @@ -1,12 +1,12 @@ - name: "Felix: Build" run: - when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/hack/test/certs/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/hack/test/certs/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - Prerequisites task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: @@ -56,8 +56,9 @@ - s390x commands: # Only building the code, not the image here because the felix image is now only used for FV tests, which - # only run on AMD64 at the moment. - - ../.semaphore/run-and-monitor build-$ARCH.log make build ARCH=$ARCH + # only run on AMD64 at the moment. Skip building protofbufs because the build fails on ARM due to missing + # image. We know they are up-to-date because an earlier build job checks already. + - ../.semaphore/run-and-monitor build-$ARCH.log make build ARCH=$ARCH SKIP_PROTOBUF=true - name: "Felix: Build - native arm64 runner" run: @@ -92,7 +93,7 @@ - name: "Felix: Windows FV capz" run: - when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/node', '/hack/test/certs/', '/process/testing/winfv/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "false or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/node', '/hack/test/certs/', '/process/testing/winfv-felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: ["Felix: Build Windows binaries"] task: secrets: @@ -100,7 +101,8 @@ - name: private-repo prologue: commands: - - export REPORT_DIR=/home/semaphore/calico/process/testing/winfv/report + - az login --service-principal -u "${AZ_SP_ID}" -p "${AZ_SP_PASSWORD}" --tenant "${AZ_TENANT_ID}" --output none + - export REPORT_DIR=/home/semaphore/report - export AZURE_SUBSCRIPTION_ID=$AZ_SUBSCRIPTION_ID - export AZURE_TENANT_ID=$AZ_TENANT_ID - export AZURE_CLIENT_ID=$AZ_SP_ID @@ -128,7 +130,7 @@ - name: "Felix: FV Tests" run: - when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - "Felix: Build" task: @@ -194,7 +196,7 @@ - name: "Felix: BPF UT/FV tests on new kernel" run: - when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" dependencies: - Prerequisites task: @@ -204,7 +206,7 @@ - export GOOGLE_APPLICATION_CREDENTIALS=$HOME/secrets/secret.google-service-account-key.json - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) - export ZONE=europe-west3-c - - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix- + - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix-ipt- - echo VM_PREFIX=${VM_PREFIX} - export REPO_NAME=$(basename $(pwd)) - export NUM_FV_BATCHES=8 @@ -224,3 +226,39 @@ - ./.semaphore/clean-up-vms ${VM_PREFIX} secrets: - name: google-service-account-for-gce + +- name: "Felix: BPF UT/FV tests on new kernel (nftables)" + run: + when: "${FORCE_RUN} or change_in(['/*', '/api/', '/libcalico-go/', '/typha/', '/felix/', '/cni-plugin/pkg/dataplane/linux/dataplane_linux.go'], {exclude: ['/**/.gitignore', '/**/README.md', '/**/LICENSE']})" + dependencies: + - Prerequisites + task: + prologue: + commands: + - cd felix + - export GOOGLE_APPLICATION_CREDENTIALS=$HOME/secrets/secret.google-service-account-key.json + - export SHORT_WORKFLOW_ID=$(echo ${SEMAPHORE_WORKFLOW_ID} | sha256sum | cut -c -8) + - export ZONE=europe-west3-c + - export VM_PREFIX=sem-${SEMAPHORE_PROJECT_NAME}-${SHORT_WORKFLOW_ID}-felix-nft- + - echo VM_PREFIX=${VM_PREFIX} + - export REPO_NAME=$(basename $(pwd)) + - export NUM_FV_BATCHES=8 + - mkdir artifacts + - ./.semaphore/create-test-vms ${VM_PREFIX} + jobs: + - name: UT/FV tests on new kernel + env_vars: + - name: FELIX_FV_NFTABLES + value: "Enabled" + execution_time_limit: + minutes: 180 + commands: + - ./.semaphore/run-tests-on-vms ${VM_PREFIX} + epilogue: + always: + commands: + - ./.semaphore/collect-artifacts-from-vms ${VM_PREFIX} + - ./.semaphore/publish-artifacts + - ./.semaphore/clean-up-vms ${VM_PREFIX} + secrets: + - name: google-service-account-for-gce diff --git a/.semaphore/semaphore.yml.d/blocks/20-kube-controllers.yml b/.semaphore/semaphore.yml.d/blocks/20-kube-controllers.yml index 00fce6a325f..6eb1ebe6e8c 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-kube-controllers.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-kube-controllers.yml @@ -6,7 +6,7 @@ task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: diff --git a/.semaphore/semaphore.yml.d/blocks/20-node.yml b/.semaphore/semaphore.yml.d/blocks/20-node.yml index ca33688c44c..9abd1880f59 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-node.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-node.yml @@ -6,7 +6,7 @@ task: agent: machine: - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 prologue: commands: @@ -24,7 +24,7 @@ task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: diff --git a/.semaphore/semaphore.yml.d/blocks/20-typha.yml b/.semaphore/semaphore.yml.d/blocks/20-typha.yml index ac1424b6a13..f83d5e708c2 100644 --- a/.semaphore/semaphore.yml.d/blocks/20-typha.yml +++ b/.semaphore/semaphore.yml.d/blocks/20-typha.yml @@ -6,7 +6,7 @@ task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: diff --git a/.semaphore/semaphore.yml.d/blocks/30-key-cert-provisioner.yml b/.semaphore/semaphore.yml.d/blocks/30-key-cert-provisioner.yml index c118d79233c..a3e9ece0c7b 100644 --- a/.semaphore/semaphore.yml.d/blocks/30-key-cert-provisioner.yml +++ b/.semaphore/semaphore.yml.d/blocks/30-key-cert-provisioner.yml @@ -6,7 +6,7 @@ task: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: diff --git a/.semaphore/semaphore.yml.d/blocks/40-openstack.yml b/.semaphore/semaphore.yml.d/blocks/40-openstack.yml index 23afc64f3c5..24e47976343 100644 --- a/.semaphore/semaphore.yml.d/blocks/40-openstack.yml +++ b/.semaphore/semaphore.yml.d/blocks/40-openstack.yml @@ -6,7 +6,7 @@ task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 prologue: commands: diff --git a/.semaphore/semaphore.yml.d/blocks/90-release.yml b/.semaphore/semaphore.yml.d/blocks/90-release.yml new file mode 100644 index 00000000000..aa5c7ed24fa --- /dev/null +++ b/.semaphore/semaphore.yml.d/blocks/90-release.yml @@ -0,0 +1,19 @@ +- name: release + run: + when: "${FORCE_RUN} or change_in(['/*', '/release/'], {exclude: ['/**/.gitignore', '/**/*.md', '/**/LICENSE']})" + execution_time_limit: + minutes: 30 + dependencies: + - Prerequisites + task: + prologue: + commands: + - cd release + jobs: + - name: make ci + commands: + - ../.semaphore/run-and-monitor release-ci.log make ci + - name: Build binary + commands: + - ../.semaphore/run-and-monitor release-build.log make build + - cache store release-${SEMAPHORE_GIT_SHA} bin diff --git a/Makefile b/Makefile index 6668ce7b8f3..7d7175de3d2 100644 --- a/Makefile +++ b/Makefile @@ -95,49 +95,51 @@ image: # using a local kind cluster. ############################################################################### E2E_FOCUS ?= "sig-network.*Conformance" +ADMINPOLICY_UNSUPPORTED_FEATURES ?= "BaselineAdminNetworkPolicy" e2e-test: $(MAKE) -C e2e build $(MAKE) -C node kind-k8st-setup - KUBECONFIG=$(KIND_KUBECONFIG) ./e2e/bin/e2e.test -ginkgo.focus=$(E2E_FOCUS) + KUBECONFIG=$(KIND_KUBECONFIG) ./e2e/bin/k8s/e2e.test -ginkgo.focus=$(E2E_FOCUS) + KUBECONFIG=$(KIND_KUBECONFIG) ./e2e/bin/adminpolicy/e2e.test -exempt-features=$(ADMINPOLICY_UNSUPPORTED_FEATURES) ############################################################################### # Release logic below ############################################################################### # Build the release tool. -hack/release/release: $(shell find ./hack/release -type f -name '*.go') - $(call build_binary, ./hack/release/cmd, $@) +release/bin/release: $(shell find ./release -type f -name '*.go') + $(call build_binary, ./release/build, $@) # Install ghr for publishing to github. -hack/release/ghr: - $(DOCKER_RUN) -e GOBIN=/go/src/$(PACKAGE_NAME)/hack/release/ $(CALICO_BUILD) go install github.com/tcnksm/ghr@v0.14.0 +bin/ghr: + $(DOCKER_RUN) -e GOBIN=/go/src/$(PACKAGE_NAME)/bin/ $(CALICO_BUILD) go install github.com/tcnksm/ghr@v0.14.0 # Build a release. -release: hack/release/release - @hack/release/release -create - -# Test the release code -release-test: - $(DOCKER_RUN) $(CALICO_BUILD) ginkgo -cover -r hack/release/pkg +release: release/bin/release + @release/bin/release release build # Publish an already built release. -release-publish: hack/release/release hack/release/ghr - @hack/release/release -publish +release-publish: release/bin/release bin/ghr + @release/bin/release release publish # Create a release branch. -create-release-branch: hack/release/release - @hack/release/release -new-branch +create-release-branch: release/bin/release + @release/bin/release branch cut -git-publish + +# Test the release code +release-test: + $(DOCKER_RUN) $(CALICO_BUILD) ginkgo -cover -r release/pkg # Currently our openstack builds either build *or* build and publish, # hence why we have two separate jobs here that do almost the same thing. build-openstack: bin/yq $(eval VERSION=$(shell bin/yq '.version' charts/calico/values.yaml)) $(info Building openstack packages for version $(VERSION)) - $(MAKE) -C hack/release/packaging release VERSION=$(VERSION) + $(MAKE) -C release/packaging release VERSION=$(VERSION) publish-openstack: bin/yq $(eval VERSION=$(shell bin/yq '.version' charts/calico/values.yaml)) $(info Publishing openstack packages for version $(VERSION)) - $(MAKE) -C hack/release/packaging release-publish VERSION=$(VERSION) + $(MAKE) -C release/packaging release-publish VERSION=$(VERSION) ## Kicks semaphore job which syncs github released helm charts with helm index file .PHONY: helm-index @@ -162,13 +164,7 @@ bin/ocp.tgz: manifests/ocp/ bin/yq ## Generates release notes for the given version. .PHONY: release-notes release-notes: -ifndef GITHUB_TOKEN - $(error GITHUB_TOKEN must be set) -endif -ifndef VERSION - $(error VERSION must be set) -endif - VERSION=$(VERSION) GITHUB_TOKEN=$(GITHUB_TOKEN) python2 ./hack/release/generate-release-notes.py + @$(MAKE) -C release release-notes ## Update the AUTHORS.md file. update-authors: @@ -185,7 +181,7 @@ endif -w /code \ -e GITHUB_TOKEN=$(GITHUB_TOKEN) \ python:3 \ - bash -c '/usr/local/bin/python hack/release/get-contributors.py >> /code/AUTHORS.md' + bash -c '/usr/local/bin/python release/get-contributors.py >> /code/AUTHORS.md' ############################################################################### # Post-release validation diff --git a/README.md b/README.md index fa1b449212d..edd77da73e3 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ ## 🐾 Welcome to Project Calico! -Project Calico is an open-source project with an active development and user community. Calico Open Source has grown to be the most widely adopted solution for container networking and security, powering 8M+ nodes daily across 166 countries. +Project Calico, created and maintained by [Tigera][tigera], is an open-source project with an active development and user community. Calico Open Source has grown to be the most widely adopted solution for container networking and security, powering 8M+ nodes daily across 166 countries. ## 🌟 Why use Calico? @@ -63,6 +63,7 @@ Project Calico is an open-source project with an active development and user com - [Technical Blog][blog] - [Careers][join]: Passionate about open source? Join our team. +[tigera]: https://www.tigera.io/ [big-cats]: https://www.tigera.io/project-calico/calico-big-cats-ambassador-program/#meet-calico-big-cats [community-meetings]: https://calendar.google.com/calendar/u/0/embed?src=tigera.io_uunmavdev5ndovf0hc4frtl0i0@group.calendar.google.com [first-issues]: https://github.com/projectcalico/calico/labels/good%20first%20issue diff --git a/api/.semaphore/semaphore.yml b/api/.semaphore/semaphore.yml index 23c1f003a16..9a4cadbbcde 100644 --- a/api/.semaphore/semaphore.yml +++ b/api/.semaphore/semaphore.yml @@ -5,7 +5,7 @@ execution_time_limit: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 auto_cancel: diff --git a/api/go.mod b/api/go.mod index 480d43b8db6..3ade0409489 100644 --- a/api/go.mod +++ b/api/go.mod @@ -5,24 +5,25 @@ go 1.22.3 require ( github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.31.1 - k8s.io/api v0.27.10 - k8s.io/apimachinery v0.27.10 - k8s.io/client-go v0.27.10 - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f + k8s.io/api v0.29.9 + k8s.io/apimachinery v0.29.9 + k8s.io/client-go v0.29.9 + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/imdario/mergo v0.3.8 // indirect @@ -36,7 +37,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.7.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect @@ -47,38 +48,38 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.90.1 // indirect - k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect + k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( - k8s.io/api => k8s.io/api v0.27.10 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.27.10 - k8s.io/apimachinery => k8s.io/apimachinery v0.27.10 - k8s.io/apiserver => k8s.io/apiserver v0.27.10 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.27.10 - k8s.io/client-go => k8s.io/client-go v0.27.10 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.27.10 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.27.10 - k8s.io/code-generator => k8s.io/code-generator v0.27.10 - k8s.io/component-base => k8s.io/component-base v0.27.10 - k8s.io/component-helpers => k8s.io/component-helpers v0.27.10 - k8s.io/controller-manager => k8s.io/controller-manager v0.27.10 - k8s.io/cri-api => k8s.io/cri-api v0.27.10 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.27.10 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.27.10 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.27.10 + k8s.io/api => k8s.io/api v0.29.9 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.29.9 + k8s.io/apimachinery => k8s.io/apimachinery v0.29.9 + k8s.io/apiserver => k8s.io/apiserver v0.29.9 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.29.9 + k8s.io/client-go => k8s.io/client-go v0.29.9 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.29.9 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.29.9 + k8s.io/code-generator => k8s.io/code-generator v0.29.9 + k8s.io/component-base => k8s.io/component-base v0.29.9 + k8s.io/component-helpers => k8s.io/component-helpers v0.29.9 + k8s.io/controller-manager => k8s.io/controller-manager v0.29.9 + k8s.io/cri-api => k8s.io/cri-api v0.29.9 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.29.9 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.29.9 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.29.9 k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d - k8s.io/kube-proxy => k8s.io/kube-proxy v0.27.10 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.27.10 - k8s.io/kubectl => k8s.io/kubectl v0.27.10 - k8s.io/kubelet => k8s.io/kubelet v0.27.10 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.27.10 - k8s.io/metrics => k8s.io/metrics v0.27.10 - k8s.io/mount-utils => k8s.io/mount-utils v0.27.10 - k8s.io/node-api => k8s.io/node-api v0.27.10 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.27.10 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.29.9 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.29.9 + k8s.io/kubectl => k8s.io/kubectl v0.29.9 + k8s.io/kubelet => k8s.io/kubelet v0.29.9 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.29.9 + k8s.io/metrics => k8s.io/metrics v0.29.9 + k8s.io/mount-utils => k8s.io/mount-utils v0.29.9 + k8s.io/node-api => k8s.io/node-api v0.29.9 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.9 ) diff --git a/api/go.sum b/api/go.sum index 00024479198..add1227acf9 100644 --- a/api/go.sum +++ b/api/go.sum @@ -7,8 +7,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= @@ -16,13 +16,12 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -48,11 +47,14 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -73,8 +75,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -106,8 +108,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -118,8 +120,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -145,8 +148,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -233,21 +236,21 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.27.10 h1:VFvsFZxiG3qeKyMvSOlO6hzrB7CGk6CC0XI1hniBI28= -k8s.io/api v0.27.10/go.mod h1:cDmAF4GtSVRO0+5hOY/Vo3lLCQMOp6FfrXZ94/gQwC0= -k8s.io/apimachinery v0.27.10 h1:AlOhsgdtNPMYDMJyUDsj2HZDLKOf1qPfvbbo5O9m4jg= -k8s.io/apimachinery v0.27.10/go.mod h1:IHu2ovJ60RqxyPSLmTel7KDLdOCRbpOxwtUBmwBnT/E= -k8s.io/client-go v0.27.10 h1:ZOrDrfTSsw+66NIkFMmnamKZ9TTs8WUaV8WRc9NhtJA= -k8s.io/client-go v0.27.10/go.mod h1:PhrjLdIJNy7L8liOPEzm6wNlMjhIRJeVbfvksTxKNqI= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/api v0.29.9 h1:FwdflpNsfMUYUOblMZNWJ4K/q0OSL5A4jGa0iOgcJco= +k8s.io/api v0.29.9/go.mod h1:fNhmzRfKaSEHCmczA/jRx6CiDKhYOnFLJBERMJAXEk8= +k8s.io/apimachinery v0.29.9 h1:YZ8HUid1TzQVz94cnNlsQjLdH0VoAhWSqz7t0q6B12A= +k8s.io/apimachinery v0.29.9/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= +k8s.io/client-go v0.29.9 h1:4f/Wz6li3rEyIPFj32XAQMtOGMM1tg7KQi1oeS6ibPg= +k8s.io/client-go v0.29.9/go.mod h1:2N1drQEZ5yiYrWVaE2Un8JiISUhl47D8pyZlYLszke4= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d h1:VcFq5n7wCJB2FQMCIHfC+f+jNcGgNMar1uKd6rVlifU= k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY= -k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= -k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/api/pkg/apis/projectcalico/v3/bgpfilter.go b/api/pkg/apis/projectcalico/v3/bgpfilter.go index 21e70ce14ec..bf3538d1e57 100644 --- a/api/pkg/apis/projectcalico/v3/bgpfilter.go +++ b/api/pkg/apis/projectcalico/v3/bgpfilter.go @@ -64,6 +64,8 @@ type BGPFilterSpec struct { type BGPFilterRuleV4 struct { CIDR string `json:"cidr,omitempty" validate:"omitempty,netv4"` + PrefixLength *BGPFilterPrefixLengthV4 `json:"prefixLength,omitempty" validate:"omitempty"` + Source BGPFilterMatchSource `json:"source,omitempty" validate:"omitempty,oneof=RemotePeers"` Interface string `json:"interface,omitempty" validate:"omitempty,bgpFilterInterface"` @@ -77,6 +79,8 @@ type BGPFilterRuleV4 struct { type BGPFilterRuleV6 struct { CIDR string `json:"cidr,omitempty" validate:"omitempty,netv6"` + PrefixLength *BGPFilterPrefixLengthV6 `json:"prefixLength,omitempty" validate:"omitempty"` + Source BGPFilterMatchSource `json:"source,omitempty" validate:"omitempty,oneof=RemotePeers"` Interface string `json:"interface,omitempty" validate:"omitempty,bgpFilterInterface"` @@ -86,6 +90,24 @@ type BGPFilterRuleV6 struct { Action BGPFilterAction `json:"action" validate:"required,filterAction"` } +type BGPFilterPrefixLengthV4 struct { + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=32 + Min *int32 `json:"min,omitempty" validate:"omitempty,bgpFilterPrefixLengthV4"` + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=32 + Max *int32 `json:"max,omitempty" validate:"omitempty,bgpFilterPrefixLengthV4"` +} + +type BGPFilterPrefixLengthV6 struct { + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=128 + Min *int32 `json:"min,omitempty" validate:"omitempty,bgpFilterPrefixLengthV6"` + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=128 + Max *int32 `json:"max,omitempty" validate:"omitempty,bgpFilterPrefixLengthV6"` +} + type BGPFilterMatchSource string const ( diff --git a/api/pkg/apis/projectcalico/v3/constants.go b/api/pkg/apis/projectcalico/v3/constants.go index 6eba5ef98e2..289204d0cad 100644 --- a/api/pkg/apis/projectcalico/v3/constants.go +++ b/api/pkg/apis/projectcalico/v3/constants.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,6 +46,10 @@ const ( OrchestratorDocker = "libnetwork" OrchestratorOpenStack = "openstack" + // Label used to denote the Tier. This is added to policies by Calico so that label matches + // can be made for tiers. + LabelTier = "projectcalico.org/tier" + // Enum options for enable/disable fields Enabled = "Enabled" Disabled = "Disabled" diff --git a/api/pkg/apis/projectcalico/v3/conversion.go b/api/pkg/apis/projectcalico/v3/conversion.go index 353ab3caf50..e9a2d3d231f 100644 --- a/api/pkg/apis/projectcalico/v3/conversion.go +++ b/api/pkg/apis/projectcalico/v3/conversion.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. package v3 @@ -14,7 +14,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error { err := scheme.AddFieldLabelConversionFunc(schema.GroupVersionKind{Group: "projectcalico.org", Version: "v3", Kind: "NetworkPolicy"}, func(label, value string) (string, string, error) { switch label { - case "metadata.name", "metadata.namespace": + case "spec.tier", "metadata.name", "metadata.namespace": return label, value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) @@ -28,7 +28,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error { err = scheme.AddFieldLabelConversionFunc(schema.GroupVersionKind{Group: "projectcalico.org", Version: "v3", Kind: "GlobalNetworkPolicy"}, func(label, value string) (string, string, error) { switch label { - case "metadata.name": + case "spec.tier", "metadata.name": return label, value, nil default: return "", "", fmt.Errorf("field label not supported: %s", label) @@ -179,5 +179,19 @@ func addConversionFuncs(scheme *runtime.Scheme) error { return err } + err = scheme.AddFieldLabelConversionFunc(schema.GroupVersionKind{Group: "projectcalico.org", Version: "v3", Kind: "Tier"}, + func(label, value string) (string, string, error) { + switch label { + case "metadata.name": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }, + ) + if err != nil { + return err + } + return nil } diff --git a/api/pkg/apis/projectcalico/v3/felixconfig.go b/api/pkg/apis/projectcalico/v3/felixconfig.go index b944145e2ba..f5fd04a3548 100644 --- a/api/pkg/apis/projectcalico/v3/felixconfig.go +++ b/api/pkg/apis/projectcalico/v3/felixconfig.go @@ -106,6 +106,7 @@ type FelixConfigurationSpec struct { // UseInternalDataplaneDriver, if true, Felix will use its internal dataplane programming logic. If false, it // will launch an external dataplane driver and communicate with it over protobuf. UseInternalDataplaneDriver *bool `json:"useInternalDataplaneDriver,omitempty"` + // DataplaneDriver filename of the external dataplane driver to use. Only used if UseInternalDataplaneDriver // is set to false. DataplaneDriver string `json:"dataplaneDriver,omitempty"` @@ -126,11 +127,13 @@ type FelixConfigurationSpec struct { // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` RouteRefreshInterval *metav1.Duration `json:"routeRefreshInterval,omitempty" configv1timescale:"seconds"` + // InterfaceRefreshInterval is the period at which Felix rescans local interfaces to verify their state. // The rescan can be disabled by setting the interval to 0. // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` InterfaceRefreshInterval *metav1.Duration `json:"interfaceRefreshInterval,omitempty" configv1timescale:"seconds"` + // IptablesRefreshInterval is the period at which Felix re-checks the IP sets // in the dataplane to ensure that no other process has accidentally broken Calico's rules. // Set to 0 to disable IP sets refresh. Note: the default for this value is lower than the @@ -140,6 +143,7 @@ type FelixConfigurationSpec struct { // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` IptablesRefreshInterval *metav1.Duration `json:"iptablesRefreshInterval,omitempty" configv1timescale:"seconds"` + // IptablesPostWriteCheckInterval is the period after Felix has done a write // to the dataplane that it schedules an extra read back in order to check the write was not // clobbered by another process. This should only occur if another application on the system @@ -147,10 +151,12 @@ type FelixConfigurationSpec struct { // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` IptablesPostWriteCheckInterval *metav1.Duration `json:"iptablesPostWriteCheckInterval,omitempty" configv1timescale:"seconds" confignamev1:"IptablesPostWriteCheckIntervalSecs"` + // IptablesLockFilePath is the location of the iptables lock file. You may need to change this // if the lock file is not in its standard location (for example if you have mapped it into Felix's // container at a different path). [Default: /run/xtables.lock] IptablesLockFilePath string `json:"iptablesLockFilePath,omitempty"` + // IptablesLockTimeout is the time that Felix will wait for the iptables lock, // or 0, to disable. To use this feature, Felix must share the iptables lock file with all other // processes that also take the lock. When running Felix inside a container, this requires the @@ -159,31 +165,39 @@ type FelixConfigurationSpec struct { // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` IptablesLockTimeout *metav1.Duration `json:"iptablesLockTimeout,omitempty" configv1timescale:"seconds" confignamev1:"IptablesLockTimeoutSecs"` + // IptablesLockProbeInterval is the time that Felix will wait between // attempts to acquire the iptables lock if it is not available. Lower values make Felix more // responsive when the lock is contended, but use more CPU. [Default: 50ms] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` IptablesLockProbeInterval *metav1.Duration `json:"iptablesLockProbeInterval,omitempty" configv1timescale:"milliseconds" confignamev1:"IptablesLockProbeIntervalMillis"` + // FeatureDetectOverride is used to override feature detection based on auto-detected platform // capabilities. Values are specified in a comma separated list with no spaces, example; // "SNATFullyRandom=true,MASQFullyRandom=false,RestoreSupportsLock=". "true" or "false" will // force the feature, empty or omitted values are auto-detected. // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9-_]+=(true|false|),)*([a-zA-Z0-9-_]+=(true|false|))?$` FeatureDetectOverride string `json:"featureDetectOverride,omitempty" validate:"omitempty,keyValueList"` + // FeatureGates is used to enable or disable tech-preview Calico features. // Values are specified in a comma separated list with no spaces, example; // "BPFConnectTimeLoadBalancingWorkaround=enabled,XyZ=false". This is // used to enable features that are not fully production ready. // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9-_]+=([^=]+),)*([a-zA-Z0-9-_]+=([^=]+))?$` FeatureGates string `json:"featureGates,omitempty" validate:"omitempty,keyValueList"` + // IpsetsRefreshInterval is the period at which Felix re-checks all iptables // state to ensure that no other process has accidentally broken Calico's rules. Set to 0 to // disable iptables refresh. [Default: 90s] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` IpsetsRefreshInterval *metav1.Duration `json:"ipsetsRefreshInterval,omitempty" configv1timescale:"seconds"` - MaxIpsetSize *int `json:"maxIpsetSize,omitempty"` + + // MaxIpsetSize is the maximum number of IP addresses that can be stored in an IP set. Not applicable + // if using the nftables backend. + MaxIpsetSize *int `json:"maxIpsetSize,omitempty"` + // IptablesBackend specifies which backend of iptables will be used. The default is Auto. // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^(?i)(Auto|FelixConfiguration|FelixConfigurationList|Legacy|NFT)?$` @@ -205,6 +219,7 @@ type FelixConfigurationSpec struct { // Ubuntu, nova-api-metadata). A value of none (case-insensitive) means that Felix should not // set up any NAT rule for the metadata path. [Default: 127.0.0.1] MetadataAddr string `json:"metadataAddr,omitempty"` + // MetadataPort is the port of the metadata server. This, combined with global.MetadataAddr (if // not 'None'), is used to set up a NAT rule, from 169.254.169.254:80 to MetadataAddr:MetadataPort. // In most cases this should not need to be changed [Default: 8775]. @@ -221,6 +236,7 @@ type FelixConfigurationSpec struct { // configure this appropriately. For example our Kubernetes and Docker integrations set the 'cali' value, // and our OpenStack integration sets the 'tap' value. [Default: cali] InterfacePrefix string `json:"interfacePrefix,omitempty"` + // InterfaceExclude is a comma-separated list of interfaces that Felix should exclude when monitoring for host // endpoints. The default value ensures that Felix ignores Kubernetes' IPVS dummy interface, which is used // internally by kube-proxy. If you want to exclude multiple interface names using a single value, the list @@ -236,6 +252,7 @@ type FelixConfigurationSpec struct { // [Default: insert] // +kubebuilder:validation:Pattern=`^(?i)(insert|append)?$` ChainInsertMode string `json:"chainInsertMode,omitempty"` + // DefaultEndpointToHostAction controls what happens to traffic that goes from a workload endpoint to the host // itself (after the traffic hits the endpoint egress policy). By default Calico blocks traffic from workload // endpoints to the host itself with an iptables "DROP" action. If you want to allow some or all traffic from @@ -245,14 +262,18 @@ type FelixConfigurationSpec struct { // from workloads after processing workload endpoint egress policy. [Default: Drop] // +kubebuilder:validation:Pattern=`^(?i)(Drop|Accept|Return)?$` DefaultEndpointToHostAction string `json:"defaultEndpointToHostAction,omitempty" validate:"omitempty,dropAcceptReturn"` + // +kubebuilder:validation:Pattern=`^(?i)(Accept|Return)?$` IptablesFilterAllowAction string `json:"iptablesFilterAllowAction,omitempty" validate:"omitempty,acceptReturn"` + // +kubebuilder:validation:Pattern=`^(?i)(Accept|Return)?$` IptablesMangleAllowAction string `json:"iptablesMangleAllowAction,omitempty" validate:"omitempty,acceptReturn"` + // IptablesFilterDenyAction controls what happens to traffic that is denied by network policy. By default Calico blocks traffic // with an iptables "DROP" action. If you want to use "REJECT" action instead you can configure it in here. // +kubebuilder:validation:Pattern=`^(?i)(Drop|Reject)?$` IptablesFilterDenyAction string `json:"iptablesFilterDenyAction,omitempty" validate:"omitempty,dropReject"` + // LogPrefix is the log prefix that Felix uses when rendering LOG rules. [Default: calico-packet] LogPrefix string `json:"logPrefix,omitempty"` @@ -262,13 +283,16 @@ type FelixConfigurationSpec struct { // LogSeverityFile is the log severity above which logs are sent to the log file. [Default: Info] // +kubebuilder:validation:Pattern=`^(?i)(Debug|Info|Warning|Error|Fatal)?$` LogSeverityFile string `json:"logSeverityFile,omitempty" validate:"omitempty,logLevel"` + // LogSeverityScreen is the log severity above which logs are sent to the stdout. [Default: Info] // +kubebuilder:validation:Pattern=`^(?i)(Debug|Info|Warning|Error|Fatal)?$` LogSeverityScreen string `json:"logSeverityScreen,omitempty" validate:"omitempty,logLevel"` + // LogSeveritySys is the log severity above which logs are sent to the syslog. Set to None for no logging to syslog. // [Default: Info] // +kubebuilder:validation:Pattern=`^(?i)(Debug|Info|Warning|Error|Fatal)?$` LogSeveritySys string `json:"logSeveritySys,omitempty" validate:"omitempty,logLevel"` + // LogDebugFilenameRegex controls which source code files have their Debug log output included in the logs. // Only logs from files with names that match the given regular expression are included. The filter only applies // to Debug level logs. @@ -276,13 +300,16 @@ type FelixConfigurationSpec struct { // IPIPEnabled overrides whether Felix should configure an IPIP interface on the host. Optional as Felix determines this based on the existing IP pools. [Default: nil (unset)] IPIPEnabled *bool `json:"ipipEnabled,omitempty" confignamev1:"IpInIpEnabled"` + // IPIPMTU is the MTU to set on the tunnel device. See Configuring MTU [Default: 1440] IPIPMTU *int `json:"ipipMTU,omitempty" confignamev1:"IpInIpMtu"` // VXLANEnabled overrides whether Felix should create the VXLAN tunnel device for IPv4 VXLAN networking. Optional as Felix determines this based on the existing IP pools. [Default: nil (unset)] VXLANEnabled *bool `json:"vxlanEnabled,omitempty" confignamev1:"VXLANEnabled"` + // VXLANMTU is the MTU to set on the IPv4 VXLAN tunnel device. See Configuring MTU [Default: 1410] VXLANMTU *int `json:"vxlanMTU,omitempty"` + // VXLANMTUV6 is the MTU to set on the IPv6 VXLAN tunnel device. See Configuring MTU [Default: 1390] VXLANMTUV6 *int `json:"vxlanMTUV6,omitempty"` VXLANPort *int `json:"vxlanPort,omitempty"` @@ -292,6 +319,7 @@ type FelixConfigurationSpec struct { // from workloads [Default: false] // +optional AllowVXLANPacketsFromWorkloads *bool `json:"allowVXLANPacketsFromWorkloads,omitempty"` + // AllowIPIPPacketsFromWorkloads controls whether Felix will add a rule to drop IPIP encapsulated traffic // from workloads [Default: false] // +optional @@ -302,12 +330,14 @@ type FelixConfigurationSpec struct { // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` ReportingInterval *metav1.Duration `json:"reportingInterval,omitempty" configv1timescale:"seconds" confignamev1:"ReportingIntervalSecs"` + // ReportingTTL is the time-to-live setting for process-wide status reports. [Default: 90s] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` ReportingTTL *metav1.Duration `json:"reportingTTL,omitempty" configv1timescale:"seconds" confignamev1:"ReportingTTLSecs"` EndpointReportingEnabled *bool `json:"endpointReportingEnabled,omitempty"` + // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` EndpointReportingDelay *metav1.Duration `json:"endpointReportingDelay,omitempty" configv1timescale:"seconds" confignamev1:"EndpointReportingDelaySecs"` @@ -330,6 +360,7 @@ type FelixConfigurationSpec struct { HealthEnabled *bool `json:"healthEnabled,omitempty"` HealthHost *string `json:"healthHost,omitempty"` HealthPort *int `json:"healthPort,omitempty"` + // HealthTimeoutOverrides allows the internal watchdog timeouts of individual subcomponents to be // overridden. This is useful for working around "false positive" liveness timeouts that can occur // in particularly stressful workloads or if CPU is constrained. For a list of active @@ -338,19 +369,25 @@ type FelixConfigurationSpec struct { // PrometheusMetricsEnabled enables the Prometheus metrics server in Felix if set to true. [Default: false] PrometheusMetricsEnabled *bool `json:"prometheusMetricsEnabled,omitempty"` + // PrometheusMetricsHost is the host that the Prometheus metrics server should bind to. [Default: empty] PrometheusMetricsHost string `json:"prometheusMetricsHost,omitempty" validate:"omitempty,prometheusHost"` + // PrometheusMetricsPort is the TCP port that the Prometheus metrics server should bind to. [Default: 9091] PrometheusMetricsPort *int `json:"prometheusMetricsPort,omitempty"` + // PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when // set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true] PrometheusGoMetricsEnabled *bool `json:"prometheusGoMetricsEnabled,omitempty"` + // PrometheusProcessMetricsEnabled disables process metrics collection, which the Prometheus client does by default, when // set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true] PrometheusProcessMetricsEnabled *bool `json:"prometheusProcessMetricsEnabled,omitempty"` + // PrometheusWireGuardMetricsEnabled disables wireguard metrics collection, which the Prometheus client does by default, when // set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true] PrometheusWireGuardMetricsEnabled *bool `json:"prometheusWireGuardMetricsEnabled,omitempty"` + // FailsafeInboundHostPorts is a list of PortProto struct objects including UDP/TCP/SCTP ports and CIDRs that Felix will // allow incoming traffic to host endpoints on irrespective of the security policy. This is useful to avoid accidentally // cutting off a host with incorrect configuration. For backwards compatibility, if the protocol is not specified, @@ -358,6 +395,7 @@ type FelixConfigurationSpec struct { // use the value "[]". The default value allows ssh access, DHCP, BGP, etcd and the Kubernetes API. // [Default: tcp:22, udp:68, tcp:179, tcp:2379, tcp:2380, tcp:5473, tcp:6443, tcp:6666, tcp:6667 ] FailsafeInboundHostPorts *[]ProtoPort `json:"failsafeInboundHostPorts,omitempty"` + // FailsafeOutboundHostPorts is a list of List of PortProto struct objects including UDP/TCP/SCTP ports and CIDRs that Felix // will allow outgoing traffic from host endpoints to irrespective of the security policy. This is useful to avoid accidentally // cutting off a host with incorrect configuration. For backwards compatibility, if the protocol is not specified, it defaults @@ -378,10 +416,12 @@ type FelixConfigurationSpec struct { // UsageReportingEnabled reports anonymous Calico version number and cluster size to projectcalico.org. Logs warnings returned by the usage // server. For example, if a significant security vulnerability has been discovered in the version of Calico being used. [Default: true] UsageReportingEnabled *bool `json:"usageReportingEnabled,omitempty"` + // UsageReportingInitialDelay controls the minimum delay before Felix makes a report. [Default: 300s] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` UsageReportingInitialDelay *metav1.Duration `json:"usageReportingInitialDelay,omitempty" configv1timescale:"seconds" confignamev1:"UsageReportingInitialDelaySecs"` + // UsageReportingInterval controls the interval at which Felix makes reports. [Default: 86400s] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` @@ -417,18 +457,23 @@ type FelixConfigurationSpec struct { DebugMemoryProfilePath string `json:"debugMemoryProfilePath,omitempty"` DebugDisableLogDropping *bool `json:"debugDisableLogDropping,omitempty"` + // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` DebugSimulateCalcGraphHangAfter *metav1.Duration `json:"debugSimulateCalcGraphHangAfter,omitempty" configv1timescale:"seconds"` + // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` DebugSimulateDataplaneHangAfter *metav1.Duration `json:"debugSimulateDataplaneHangAfter,omitempty" configv1timescale:"seconds"` + // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` DebugSimulateDataplaneApplyDelay *metav1.Duration `json:"debugSimulateDataplaneApplyDelay,omitempty" configv1timescale:"seconds"` + // DebugHost is the host IP or hostname to bind the debug port to. Only used // if DebugPort is set. [Default:localhost] DebugHost *string `json:"debugHost,omitempty"` + // DebugPort if set, enables Felix's debug HTTP port, which allows memory and CPU profiles // to be retrieved. The debug port is not secure, it should not be exposed to the internet. DebugPort *int `json:"debugPort,omitempty" validate:"omitempty,gte=0,lte=65535"` @@ -449,18 +494,40 @@ type FelixConfigurationSpec struct { // NFTablesMode configures nftables support in Felix. [Default: Disabled] NFTablesMode *NFTablesMode `json:"nftablesMode,omitempty"` + // NftablesRefreshInterval controls the interval at which Felix periodically refreshes the nftables rules. [Default: 90s] + NftablesRefreshInterval *metav1.Duration `json:"nftablesRefreshInterval,omitempty" configv1timescale:"seconds"` + + // +kubebuilder:validation:Pattern=`^(?i)(Accept|Return)?$` + NftablesFilterAllowAction string `json:"nftablesFilterAllowAction,omitempty" validate:"omitempty,acceptReturn"` + + // +kubebuilder:validation:Pattern=`^(?i)(Accept|Return)?$` + NftablesMangleAllowAction string `json:"nftablesMangleAllowAction,omitempty" validate:"omitempty,acceptReturn"` + + // FilterDenyAction controls what happens to traffic that is denied by network policy. By default Calico blocks traffic + // with a "drop" action. If you want to use a "reject" action instead you can configure it here. + // +kubebuilder:validation:Pattern=`^(?i)(Drop|Reject)?$` + NftablesFilterDenyAction string `json:"nftablesFilterDenyAction,omitempty" validate:"omitempty,dropReject"` + + // MarkMask is the mask that Felix selects its nftables Mark bits from. Should be a 32 bit hexadecimal + // number with at least 8 bits set, none of which clash with any other mark bits in use on the system. + // [Default: 0xffff0000] + NftablesMarkMask *uint32 `json:"nftablesMarkMask,omitempty"` + // BPFEnabled, if enabled Felix will use the BPF dataplane. [Default: false] BPFEnabled *bool `json:"bpfEnabled,omitempty" validate:"omitempty"` + // BPFDisableUnprivileged, if enabled, Felix sets the kernel.unprivileged_bpf_disabled sysctl to disable // unprivileged use of BPF. This ensures that unprivileged users cannot access Calico's BPF maps and // cannot insert their own BPF programs to interfere with Calico's. [Default: true] BPFDisableUnprivileged *bool `json:"bpfDisableUnprivileged,omitempty" validate:"omitempty"` + // BPFLogLevel controls the log level of the BPF programs when in BPF dataplane mode. One of "Off", "Info", or // "Debug". The logs are emitted to the BPF trace pipe, accessible with the command `tc exec bpf debug`. // [Default: Off]. // +optional // +kubebuilder:validation:Pattern=`^(?i)(Off|Info|Debug)?$` BPFLogLevel string `json:"bpfLogLevel" validate:"omitempty,bpfLogLevel"` + // BPFLogFilters is a map of key=values where the value is // a pcap filter expression and the key is an interface name with 'all' // denoting all interfaces, 'weps' all workload endpoints and 'heps' all host @@ -471,34 +538,41 @@ type FelixConfigurationSpec struct { // [Default: unset - means all debug logs are emitted] // +optional BPFLogFilters *map[string]string `json:"bpfLogFilters,omitempty" validate:"omitempty,bpfLogFilters"` + // BPFCTLBLogFilter specifies, what is logged by connect time load balancer when BPFLogLevel is // debug. Currently has to be specified as 'all' when BPFLogFilters is set // to see CTLB logs. // [Default: unset - means logs are emitted when BPFLogLevel id debug and BPFLogFilters not set.] // +optional BPFCTLBLogFilter string `json:"bpfCTLBLogFilter,omitempty" validate:"omitempty"` + // BPFDataIfacePattern is a regular expression that controls which interfaces Felix should attach BPF programs to // in order to catch traffic to/from the network. This needs to match the interfaces that Calico workload traffic // flows over as well as any interfaces that handle incoming traffic to nodeports and services from outside the // cluster. It should not match the workload interfaces (usually named cali...). BPFDataIfacePattern string `json:"bpfDataIfacePattern,omitempty" validate:"omitempty,regexp"` + // BPFL3IfacePattern is a regular expression that allows to list tunnel devices like wireguard or vxlan (i.e., L3 devices) // in addition to BPFDataIfacePattern. That is, tunnel interfaces not created by Calico, that Calico workload traffic flows // over as well as any interfaces that handle incoming traffic to nodeports and services from outside the cluster. BPFL3IfacePattern string `json:"bpfL3IfacePattern,omitempty" validate:"omitempty,regexp"` + // BPFConnectTimeLoadBalancingEnabled when in BPF mode, controls whether Felix installs the connection-time load // balancer. The connect-time load balancer is required for the host to be able to reach Kubernetes services // and it improves the performance of pod-to-service connections. The only reason to disable it is for debugging // purposes. This will be deprecated. Use BPFConnectTimeLoadBalancing [Default: true] BPFConnectTimeLoadBalancingEnabled *bool `json:"bpfConnectTimeLoadBalancingEnabled,omitempty" validate:"omitempty"` + // BPFConnectTimeLoadBalancing when in BPF mode, controls whether Felix installs the connect-time load // balancer. The connect-time load balancer is required for the host to be able to reach Kubernetes services // and it improves the performance of pod-to-service connections.When set to TCP, connect time load balancing // is available only for services with TCP ports. [Default: TCP] BPFConnectTimeLoadBalancing *BPFConnectTimeLBType `json:"bpfConnectTimeLoadBalancing,omitempty" validate:"omitempty,oneof=TCP Enabled Disabled"` + // BPFHostNetworkedNATWithoutCTLB when in BPF mode, controls whether Felix does a NAT without CTLB. This along with BPFConnectTimeLoadBalancing // determines the CTLB behavior. [Default: Enabled] BPFHostNetworkedNATWithoutCTLB *BPFHostNetworkedNATType `json:"bpfHostNetworkedNATWithoutCTLB,omitempty" validate:"omitempty,oneof=Enabled Disabled"` + // BPFExternalServiceMode in BPF mode, controls how connections from outside the cluster to services (node ports // and cluster IPs) are forwarded to remote workloads. If set to "Tunnel" then both request and response traffic // is tunneled to the remote node. If set to "DSR", the request traffic is tunneled but the response traffic @@ -506,27 +580,33 @@ type FelixConfigurationSpec struct { // node; this requires a permissive L2 network. [Default: Tunnel] // +kubebuilder:validation:Pattern=`^(?i)(Tunnel|DSR)?$` BPFExternalServiceMode string `json:"bpfExternalServiceMode,omitempty" validate:"omitempty,bpfServiceMode"` + // BPFDSROptoutCIDRs is a list of CIDRs which are excluded from DSR. That is, clients // in those CIDRs will accesses nodeports as if BPFExternalServiceMode was set to // Tunnel. BPFDSROptoutCIDRs *[]string `json:"bpfDSROptoutCIDRs,omitempty" validate:"omitempty,cidrs"` + // BPFExtToServiceConnmark in BPF mode, control a 32bit mark that is set on connections from an // external client to a local service. This mark allows us to control how packets of that // connection are routed within the host and how is routing interpreted by RPF check. [Default: 0] BPFExtToServiceConnmark *int `json:"bpfExtToServiceConnmark,omitempty" validate:"omitempty,gte=0,lte=4294967295"` + // BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF mode, Felix will proactively clean up the upstream // Kubernetes kube-proxy's iptables chains. Should only be enabled if kube-proxy is not running. [Default: true] BPFKubeProxyIptablesCleanupEnabled *bool `json:"bpfKubeProxyIptablesCleanupEnabled,omitempty" validate:"omitempty"` + // BPFKubeProxyMinSyncPeriod, in BPF mode, controls the minimum time between updates to the dataplane for Felix's // embedded kube-proxy. Lower values give reduced set-up latency. Higher values reduce Felix CPU usage by // batching up more work. [Default: 1s] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` BPFKubeProxyMinSyncPeriod *metav1.Duration `json:"bpfKubeProxyMinSyncPeriod,omitempty" validate:"omitempty" configv1timescale:"seconds"` + // BPFKubeProxyEndpointSlicesEnabled is deprecated and has no effect. BPF // kube-proxy always accepts endpoint slices. This option will be removed in // the next release. BPFKubeProxyEndpointSlicesEnabled *bool `json:"bpfKubeProxyEndpointSlicesEnabled,omitempty" validate:"omitempty"` + // BPFPSNATPorts sets the range from which we randomly pick a port if there is a source port // collision. This should be within the ephemeral range as defined by RFC 6056 (1024–65535) and // preferably outside the ephemeral ranges used by common operating systems. Linux uses @@ -534,53 +614,73 @@ type FelixConfigurationSpec struct { // a problem if this range overlaps with the operating systems. Both ends of the range are // inclusive. [Default: 20000:29999] BPFPSNATPorts *numorstring.Port `json:"bpfPSNATPorts,omitempty"` + // BPFMapSizeNATFrontend sets the size for nat front end map. // FrontendMap should be large enough to hold an entry for each nodeport, // external IP and each port in each service. BPFMapSizeNATFrontend *int `json:"bpfMapSizeNATFrontend,omitempty"` + // BPFMapSizeNATBackend sets the size for nat back end map. // This is the total number of endpoints. This is mostly // more than the size of the number of services. BPFMapSizeNATBackend *int `json:"bpfMapSizeNATBackend,omitempty"` BPFMapSizeNATAffinity *int `json:"bpfMapSizeNATAffinity,omitempty"` + // BPFMapSizeRoute sets the size for the routes map. The routes map should be large enough // to hold one entry per workload and a handful of entries per host (enough to cover its own IPs and // tunnel IPs). BPFMapSizeRoute *int `json:"bpfMapSizeRoute,omitempty"` + // BPFMapSizeConntrack sets the size for the conntrack map. This map must be large enough to hold // an entry for each active connection. Warning: changing the size of the conntrack map can cause disruption. BPFMapSizeConntrack *int `json:"bpfMapSizeConntrack,omitempty"` + // BPFMapSizeIPSets sets the size for ipsets map. The IP sets map must be large enough to hold an entry // for each endpoint matched by every selector in the source/destination matches in network policy. Selectors // such as "all()" can result in large numbers of entries (one entry per endpoint in that case). BPFMapSizeIPSets *int `json:"bpfMapSizeIPSets,omitempty"` + // BPFMapSizeIfState sets the size for ifstate map. The ifstate map must be large enough to hold an entry // for each device (host + workloads) on a host. BPFMapSizeIfState *int `json:"bpfMapSizeIfState,omitempty"` + // BPFHostConntrackBypass Controls whether to bypass Linux conntrack in BPF mode for // workloads and services. [Default: true - bypass Linux conntrack] BPFHostConntrackBypass *bool `json:"bpfHostConntrackBypass,omitempty"` + // BPFEnforceRPF enforce strict RPF on all host interfaces with BPF programs regardless of // what is the per-interfaces or global setting. Possible values are Disabled, Strict // or Loose. [Default: Loose] // +kubebuilder:validation:Pattern=`^(?i)(Disabled|Strict|Loose)?$` BPFEnforceRPF string `json:"bpfEnforceRPF,omitempty"` + // BPFPolicyDebugEnabled when true, Felix records detailed information // about the BPF policy programs, which can be examined with the calico-bpf command-line tool. BPFPolicyDebugEnabled *bool `json:"bpfPolicyDebugEnabled,omitempty"` + // BPFForceTrackPacketsFromIfaces in BPF mode, forces traffic from these interfaces // to skip Calico's iptables NOTRACK rule, allowing traffic from those interfaces to be // tracked by Linux conntrack. Should only be used for interfaces that are not used for // the Calico fabric. For example, a docker bridge device for non-Calico-networked // containers. [Default: docker+] BPFForceTrackPacketsFromIfaces *[]string `json:"bpfForceTrackPacketsFromIfaces,omitempty" validate:"omitempty,ifaceFilterSlice"` + // BPFDisableGROForIfaces is a regular expression that controls which interfaces Felix should disable the // Generic Receive Offload [GRO] option. It should not match the workload interfaces (usually named cali...). BPFDisableGROForIfaces string `json:"bpfDisableGROForIfaces,omitempty" validate:"omitempty,regexp"` + // BPFExcludeCIDRsFromNAT is a list of CIDRs that are to be excluded from NAT // resolution so that host can handle them. A typical usecase is node local // DNS cache. BPFExcludeCIDRsFromNAT *[]string `json:"bpfExcludeCIDRsFromNAT,omitempty" validate:"omitempty,cidrs"` + // BPFRedirectToPeer controls which whether it is allowed to forward straight to the + // peer side of the workload devices. It is allowed for any host L2 devices by default + // (L2Only), but it breaks TCP dump on the host side of workload device as it bypasses + // it on ingress. Value of Enabled also allows redirection from L3 host devices like + // IPIP tunnel or Wireguard directly to the peer side of the workload's device. This + // makes redirection faster, however, it breaks tools like tcpdump on the peer side. + // Use Enabled with caution. [Default: L2Only] + BPFRedirectToPeer string `json:"bpfRedirectToPeer,omitempty"` // RouteSource configures where Felix gets its routing information. // - WorkloadIPs: use workload endpoints to construct routes. @@ -604,24 +704,34 @@ type FelixConfigurationSpec struct { // WireguardEnabled controls whether Wireguard is enabled for IPv4 (encapsulating IPv4 traffic over an IPv4 underlay network). [Default: false] WireguardEnabled *bool `json:"wireguardEnabled,omitempty"` + // WireguardEnabledV6 controls whether Wireguard is enabled for IPv6 (encapsulating IPv6 traffic over an IPv6 underlay network). [Default: false] WireguardEnabledV6 *bool `json:"wireguardEnabledV6,omitempty"` + // WireguardListeningPort controls the listening port used by IPv4 Wireguard. [Default: 51820] WireguardListeningPort *int `json:"wireguardListeningPort,omitempty" validate:"omitempty,gt=0,lte=65535"` + // WireguardListeningPortV6 controls the listening port used by IPv6 Wireguard. [Default: 51821] WireguardListeningPortV6 *int `json:"wireguardListeningPortV6,omitempty" validate:"omitempty,gt=0,lte=65535"` + // WireguardRoutingRulePriority controls the priority value to use for the Wireguard routing rule. [Default: 99] WireguardRoutingRulePriority *int `json:"wireguardRoutingRulePriority,omitempty" validate:"omitempty,gt=0,lt=32766"` + // WireguardInterfaceName specifies the name to use for the IPv4 Wireguard interface. [Default: wireguard.cali] WireguardInterfaceName string `json:"wireguardInterfaceName,omitempty" validate:"omitempty,interface"` + // WireguardInterfaceNameV6 specifies the name to use for the IPv6 Wireguard interface. [Default: wg-v6.cali] WireguardInterfaceNameV6 string `json:"wireguardInterfaceNameV6,omitempty" validate:"omitempty,interface"` + // WireguardMTU controls the MTU on the IPv4 Wireguard interface. See Configuring MTU [Default: 1440] WireguardMTU *int `json:"wireguardMTU,omitempty"` + // WireguardMTUV6 controls the MTU on the IPv6 Wireguard interface. See Configuring MTU [Default: 1420] WireguardMTUV6 *int `json:"wireguardMTUV6,omitempty"` + // WireguardHostEncryptionEnabled controls whether Wireguard host-to-host encryption is enabled. [Default: false] WireguardHostEncryptionEnabled *bool `json:"wireguardHostEncryptionEnabled,omitempty"` + // WireguardKeepAlive controls Wireguard PersistentKeepalive option. Set 0 to disable. [Default: 0] // +kubebuilder:validation:Type=string // +kubebuilder:validation:Pattern=`^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$` diff --git a/api/pkg/apis/projectcalico/v3/globalnetworkpolicy.go b/api/pkg/apis/projectcalico/v3/globalnetworkpolicy.go index d0bc3b2b52f..c17de187810 100644 --- a/api/pkg/apis/projectcalico/v3/globalnetworkpolicy.go +++ b/api/pkg/apis/projectcalico/v3/globalnetworkpolicy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017,2019-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,11 +46,17 @@ type GlobalNetworkPolicy struct { } type GlobalNetworkPolicySpec struct { + // The name of the tier that this policy belongs to. If this is omitted, the default + // tier (name is "default") is assumed. The specified tier must exist in order to create + // security policies within the tier, the "default" tier is created automatically if it + // does not exist, this means for deployments requiring only a single Tier, the tier name + // may be omitted on all policy management requests. + Tier string `json:"tier,omitempty" validate:"omitempty,name"` // Order is an optional field that specifies the order in which the policy is applied. // Policies with higher "order" are applied after those with lower - // order. If the order is omitted, it may be considered to be "infinite" - i.e. the + // order within the same tier. If the order is omitted, it may be considered to be "infinite" - i.e. the // policy will be applied last. Policies with identical order will be applied in - // alphanumerical order based on the Policy "Name". + // alphanumerical order based on the Policy "Name" within the tier. Order *float64 `json:"order,omitempty"` // The ordered set of ingress rules. Each rule contains a set of packet match criteria and // a corresponding action to apply. diff --git a/api/pkg/apis/projectcalico/v3/networkpolicy.go b/api/pkg/apis/projectcalico/v3/networkpolicy.go index 0dddbc1b8ea..1ff5d5945df 100644 --- a/api/pkg/apis/projectcalico/v3/networkpolicy.go +++ b/api/pkg/apis/projectcalico/v3/networkpolicy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017,2019,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -44,11 +44,17 @@ type NetworkPolicy struct { } type NetworkPolicySpec struct { + // The name of the tier that this policy belongs to. If this is omitted, the default + // tier (name is "default") is assumed. The specified tier must exist in order to create + // security policies within the tier, the "default" tier is created automatically if it + // does not exist, this means for deployments requiring only a single Tier, the tier name + // may be omitted on all policy management requests. + Tier string `json:"tier,omitempty" validate:"omitempty,name"` // Order is an optional field that specifies the order in which the policy is applied. // Policies with higher "order" are applied after those with lower - // order. If the order is omitted, it may be considered to be "infinite" - i.e. the + // order within the same tier. If the order is omitted, it may be considered to be "infinite" - i.e. the // policy will be applied last. Policies with identical order will be applied in - // alphanumerical order based on the Policy "Name". + // alphanumerical order based on the Policy "Name" within the tier. Order *float64 `json:"order,omitempty"` // The ordered set of ingress rules. Each rule contains a set of packet match criteria and // a corresponding action to apply. diff --git a/api/pkg/apis/projectcalico/v3/register.go b/api/pkg/apis/projectcalico/v3/register.go index 870be0cdb4e..74dd7f92303 100644 --- a/api/pkg/apis/projectcalico/v3/register.go +++ b/api/pkg/apis/projectcalico/v3/register.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. package v3 @@ -56,6 +56,8 @@ var ( &BlockAffinityList{}, &BGPFilter{}, &BGPFilterList{}, + &Tier{}, + &TierList{}, } ) diff --git a/api/pkg/apis/projectcalico/v3/tier.go b/api/pkg/apis/projectcalico/v3/tier.go new file mode 100644 index 00000000000..d247e6fe255 --- /dev/null +++ b/api/pkg/apis/projectcalico/v3/tier.go @@ -0,0 +1,89 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v3 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +const ( + KindTier = "Tier" + KindTierList = "TierList" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Tier contains a set of policies that are applied to packets. Multiple tiers may +// be created and each tier is applied in the order specified in the tier specification. +// Tier is globally-scoped (i.e. not Namespaced). +type Tier struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // Specification of the Tier. + Spec TierSpec `json:"spec,omitempty" protobuf:"bytes,2,rep,name=spec"` +} + +const ( + DefaultTierOrder = float64(1_000_000) // 1Million + AdminNetworkPolicyTierOrder = float64(1_000) // 1K +) + +// TierSpec contains the specification for a security policy tier resource. +type TierSpec struct { + // Order is an optional field that specifies the order in which the tier is applied. + // Tiers with higher "order" are applied after those with lower order. If the order + // is omitted, it may be considered to be "infinite" - i.e. the tier will be applied + // last. Tiers with identical order will be applied in alphanumerical order based + // on the Tier "Name". + Order *float64 `json:"order,omitempty" protobuf:"bytes,1,opt,name=order"` + // DefaultAction specifies the action applied to workloads selected by a policy in the tier, + // but not rule matched the workload's traffic. + // [Default: Deny] + // +kubebuilder:validation:Enum=Pass;Deny + DefaultAction *Action `json:"defaultAction,omitempty" validate:"omitempty,oneof=Deny Pass"` +} + +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TierList contains a list of Tier resources. +type TierList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"` + Items []Tier `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// NewTier creates a new (zeroed) Tier struct with the TypeMetadata initialised to the current +// version. +func NewTier() *Tier { + return &Tier{ + TypeMeta: metav1.TypeMeta{ + Kind: KindTier, + APIVersion: GroupVersionCurrent, + }, + } +} + +// NewTierList creates a new (zeroed) TierList struct with the TypeMetadata initialised to the current +// version. +func NewTierList() *TierList { + return &TierList{ + TypeMeta: metav1.TypeMeta{ + Kind: KindTierList, + APIVersion: GroupVersionCurrent, + }, + } +} diff --git a/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go b/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go index 35bdeda080d..6d44fb614d2 100644 --- a/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go +++ b/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go @@ -239,9 +239,66 @@ func (in *BGPFilterList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BGPFilterPrefixLengthV4) DeepCopyInto(out *BGPFilterPrefixLengthV4) { + *out = *in + if in.Min != nil { + in, out := &in.Min, &out.Min + *out = new(int32) + **out = **in + } + if in.Max != nil { + in, out := &in.Max, &out.Max + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BGPFilterPrefixLengthV4. +func (in *BGPFilterPrefixLengthV4) DeepCopy() *BGPFilterPrefixLengthV4 { + if in == nil { + return nil + } + out := new(BGPFilterPrefixLengthV4) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BGPFilterPrefixLengthV6) DeepCopyInto(out *BGPFilterPrefixLengthV6) { + *out = *in + if in.Min != nil { + in, out := &in.Min, &out.Min + *out = new(int32) + **out = **in + } + if in.Max != nil { + in, out := &in.Max, &out.Max + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BGPFilterPrefixLengthV6. +func (in *BGPFilterPrefixLengthV6) DeepCopy() *BGPFilterPrefixLengthV6 { + if in == nil { + return nil + } + out := new(BGPFilterPrefixLengthV6) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BGPFilterRuleV4) DeepCopyInto(out *BGPFilterRuleV4) { *out = *in + if in.PrefixLength != nil { + in, out := &in.PrefixLength, &out.PrefixLength + *out = new(BGPFilterPrefixLengthV4) + (*in).DeepCopyInto(*out) + } return } @@ -258,6 +315,11 @@ func (in *BGPFilterRuleV4) DeepCopy() *BGPFilterRuleV4 { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BGPFilterRuleV6) DeepCopyInto(out *BGPFilterRuleV6) { *out = *in + if in.PrefixLength != nil { + in, out := &in.PrefixLength, &out.PrefixLength + *out = new(BGPFilterPrefixLengthV6) + (*in).DeepCopyInto(*out) + } return } @@ -277,22 +339,30 @@ func (in *BGPFilterSpec) DeepCopyInto(out *BGPFilterSpec) { if in.ExportV4 != nil { in, out := &in.ExportV4, &out.ExportV4 *out = make([]BGPFilterRuleV4, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.ImportV4 != nil { in, out := &in.ImportV4, &out.ImportV4 *out = make([]BGPFilterRuleV4, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.ExportV6 != nil { in, out := &in.ExportV6, &out.ExportV6 *out = make([]BGPFilterRuleV6, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.ImportV6 != nil { in, out := &in.ImportV6, &out.ImportV6 *out = make([]BGPFilterRuleV6, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -1306,6 +1376,16 @@ func (in *FelixConfigurationSpec) DeepCopyInto(out *FelixConfigurationSpec) { *out = new(NFTablesMode) **out = **in } + if in.NftablesRefreshInterval != nil { + in, out := &in.NftablesRefreshInterval, &out.NftablesRefreshInterval + *out = new(v1.Duration) + **out = **in + } + if in.NftablesMarkMask != nil { + in, out := &in.NftablesMarkMask, &out.NftablesMarkMask + *out = new(uint32) + **out = **in + } if in.BPFEnabled != nil { in, out := &in.BPFEnabled, &out.BPFEnabled *out = new(bool) @@ -2911,6 +2991,92 @@ func (in *ServiceMatch) DeepCopy() *ServiceMatch { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Tier) DeepCopyInto(out *Tier) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tier. +func (in *Tier) DeepCopy() *Tier { + if in == nil { + return nil + } + out := new(Tier) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Tier) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TierList) DeepCopyInto(out *TierList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Tier, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TierList. +func (in *TierList) DeepCopy() *TierList { + if in == nil { + return nil + } + out := new(TierList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TierList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TierSpec) DeepCopyInto(out *TierSpec) { + *out = *in + if in.Order != nil { + in, out := &in.Order, &out.Order + *out = new(float64) + **out = **in + } + if in.DefaultAction != nil { + in, out := &in.DefaultAction, &out.DefaultAction + *out = new(Action) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TierSpec. +func (in *TierSpec) DeepCopy() *TierSpec { + if in == nil { + return nil + } + out := new(TierSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WorkloadEndpointControllerConfig) DeepCopyInto(out *WorkloadEndpointControllerConfig) { *out = *in diff --git a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_projectcalico_client.go b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_projectcalico_client.go index 5ef981a190d..f77389f4521 100644 --- a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_projectcalico_client.go +++ b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_projectcalico_client.go @@ -82,6 +82,10 @@ func (c *FakeProjectcalicoV3) Profiles() v3.ProfileInterface { return &FakeProfiles{c} } +func (c *FakeProjectcalicoV3) Tiers() v3.TierInterface { + return &FakeTiers{c} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeProjectcalicoV3) RESTClient() rest.Interface { diff --git a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_tier.go b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_tier.go new file mode 100644 index 00000000000..a6fdcadcaac --- /dev/null +++ b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/fake/fake_tier.go @@ -0,0 +1,107 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeTiers implements TierInterface +type FakeTiers struct { + Fake *FakeProjectcalicoV3 +} + +var tiersResource = v3.SchemeGroupVersion.WithResource("tiers") + +var tiersKind = v3.SchemeGroupVersion.WithKind("Tier") + +// Get takes name of the tier, and returns the corresponding tier object, and an error if there is any. +func (c *FakeTiers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v3.Tier, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(tiersResource, name), &v3.Tier{}) + if obj == nil { + return nil, err + } + return obj.(*v3.Tier), err +} + +// List takes label and field selectors, and returns the list of Tiers that match those selectors. +func (c *FakeTiers) List(ctx context.Context, opts v1.ListOptions) (result *v3.TierList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(tiersResource, tiersKind, opts), &v3.TierList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v3.TierList{ListMeta: obj.(*v3.TierList).ListMeta} + for _, item := range obj.(*v3.TierList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested tiers. +func (c *FakeTiers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(tiersResource, opts)) +} + +// Create takes the representation of a tier and creates it. Returns the server's representation of the tier, and an error, if there is any. +func (c *FakeTiers) Create(ctx context.Context, tier *v3.Tier, opts v1.CreateOptions) (result *v3.Tier, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(tiersResource, tier), &v3.Tier{}) + if obj == nil { + return nil, err + } + return obj.(*v3.Tier), err +} + +// Update takes the representation of a tier and updates it. Returns the server's representation of the tier, and an error, if there is any. +func (c *FakeTiers) Update(ctx context.Context, tier *v3.Tier, opts v1.UpdateOptions) (result *v3.Tier, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(tiersResource, tier), &v3.Tier{}) + if obj == nil { + return nil, err + } + return obj.(*v3.Tier), err +} + +// Delete takes name of the tier and deletes it. Returns an error if one occurs. +func (c *FakeTiers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(tiersResource, name, opts), &v3.Tier{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeTiers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(tiersResource, listOpts) + + _, err := c.Fake.Invokes(action, &v3.TierList{}) + return err +} + +// Patch applies the patch and returns the patched tier. +func (c *FakeTiers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v3.Tier, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(tiersResource, name, pt, data, subresources...), &v3.Tier{}) + if obj == nil { + return nil, err + } + return obj.(*v3.Tier), err +} diff --git a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/generated_expansion.go b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/generated_expansion.go index 8ec8b5aa554..0f60d9adcfe 100644 --- a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/generated_expansion.go +++ b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/generated_expansion.go @@ -37,3 +37,5 @@ type NetworkPolicyExpansion interface{} type NetworkSetExpansion interface{} type ProfileExpansion interface{} + +type TierExpansion interface{} diff --git a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/projectcalico_client.go b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/projectcalico_client.go index edcad9a7e97..5ac91037b84 100644 --- a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/projectcalico_client.go +++ b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/projectcalico_client.go @@ -31,6 +31,7 @@ type ProjectcalicoV3Interface interface { NetworkPoliciesGetter NetworkSetsGetter ProfilesGetter + TiersGetter } // ProjectcalicoV3Client is used to interact with features provided by the projectcalico.org group. @@ -106,6 +107,10 @@ func (c *ProjectcalicoV3Client) Profiles() ProfileInterface { return newProfiles(c) } +func (c *ProjectcalicoV3Client) Tiers() TierInterface { + return newTiers(c) +} + // NewForConfig creates a new ProjectcalicoV3Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/tier.go b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/tier.go new file mode 100644 index 00000000000..efda6e6099b --- /dev/null +++ b/api/pkg/client/clientset_generated/clientset/typed/projectcalico/v3/tier.go @@ -0,0 +1,154 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Code generated by client-gen. DO NOT EDIT. + +package v3 + +import ( + "context" + "time" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + scheme "github.com/projectcalico/api/pkg/client/clientset_generated/clientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// TiersGetter has a method to return a TierInterface. +// A group's client should implement this interface. +type TiersGetter interface { + Tiers() TierInterface +} + +// TierInterface has methods to work with Tier resources. +type TierInterface interface { + Create(ctx context.Context, tier *v3.Tier, opts v1.CreateOptions) (*v3.Tier, error) + Update(ctx context.Context, tier *v3.Tier, opts v1.UpdateOptions) (*v3.Tier, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v3.Tier, error) + List(ctx context.Context, opts v1.ListOptions) (*v3.TierList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v3.Tier, err error) + TierExpansion +} + +// tiers implements TierInterface +type tiers struct { + client rest.Interface +} + +// newTiers returns a Tiers +func newTiers(c *ProjectcalicoV3Client) *tiers { + return &tiers{ + client: c.RESTClient(), + } +} + +// Get takes name of the tier, and returns the corresponding tier object, and an error if there is any. +func (c *tiers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v3.Tier, err error) { + result = &v3.Tier{} + err = c.client.Get(). + Resource("tiers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Tiers that match those selectors. +func (c *tiers) List(ctx context.Context, opts v1.ListOptions) (result *v3.TierList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v3.TierList{} + err = c.client.Get(). + Resource("tiers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested tiers. +func (c *tiers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("tiers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a tier and creates it. Returns the server's representation of the tier, and an error, if there is any. +func (c *tiers) Create(ctx context.Context, tier *v3.Tier, opts v1.CreateOptions) (result *v3.Tier, err error) { + result = &v3.Tier{} + err = c.client.Post(). + Resource("tiers"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(tier). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a tier and updates it. Returns the server's representation of the tier, and an error, if there is any. +func (c *tiers) Update(ctx context.Context, tier *v3.Tier, opts v1.UpdateOptions) (result *v3.Tier, err error) { + result = &v3.Tier{} + err = c.client.Put(). + Resource("tiers"). + Name(tier.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(tier). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the tier and deletes it. Returns an error if one occurs. +func (c *tiers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("tiers"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *tiers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("tiers"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched tier. +func (c *tiers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v3.Tier, err error) { + result = &v3.Tier{} + err = c.client.Patch(pt). + Resource("tiers"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/api/pkg/client/informers_generated/externalversions/factory.go b/api/pkg/client/informers_generated/externalversions/factory.go index f07b66208dc..3279837ff1e 100644 --- a/api/pkg/client/informers_generated/externalversions/factory.go +++ b/api/pkg/client/informers_generated/externalversions/factory.go @@ -28,6 +28,7 @@ type sharedInformerFactory struct { lock sync.Mutex defaultResync time.Duration customResync map[reflect.Type]time.Duration + transform cache.TransformFunc informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -66,6 +67,14 @@ func WithNamespace(namespace string) SharedInformerOption { } } +// WithTransform sets a transform on all informers. +func WithTransform(transform cache.TransformFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.transform = transform + return factory + } +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client clientset.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -170,6 +179,7 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) + informer.SetTransform(f.transform) f.informers[informerType] = informer return informer diff --git a/api/pkg/client/informers_generated/externalversions/generic.go b/api/pkg/client/informers_generated/externalversions/generic.go index d54b91a9cef..c603502b5a4 100644 --- a/api/pkg/client/informers_generated/externalversions/generic.go +++ b/api/pkg/client/informers_generated/externalversions/generic.go @@ -73,6 +73,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Projectcalico().V3().NetworkSets().Informer()}, nil case v3.SchemeGroupVersion.WithResource("profiles"): return &genericInformer{resource: resource.GroupResource(), informer: f.Projectcalico().V3().Profiles().Informer()}, nil + case v3.SchemeGroupVersion.WithResource("tiers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Projectcalico().V3().Tiers().Informer()}, nil } diff --git a/api/pkg/client/informers_generated/externalversions/projectcalico/v3/interface.go b/api/pkg/client/informers_generated/externalversions/projectcalico/v3/interface.go index 481d4664342..9a3545f3ef9 100644 --- a/api/pkg/client/informers_generated/externalversions/projectcalico/v3/interface.go +++ b/api/pkg/client/informers_generated/externalversions/projectcalico/v3/interface.go @@ -44,6 +44,8 @@ type Interface interface { NetworkSets() NetworkSetInformer // Profiles returns a ProfileInformer. Profiles() ProfileInformer + // Tiers returns a TierInformer. + Tiers() TierInformer } type version struct { @@ -141,3 +143,8 @@ func (v *version) NetworkSets() NetworkSetInformer { func (v *version) Profiles() ProfileInformer { return &profileInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } + +// Tiers returns a TierInformer. +func (v *version) Tiers() TierInformer { + return &tierInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/api/pkg/client/informers_generated/externalversions/projectcalico/v3/tier.go b/api/pkg/client/informers_generated/externalversions/projectcalico/v3/tier.go new file mode 100644 index 00000000000..9d9ccf8b26e --- /dev/null +++ b/api/pkg/client/informers_generated/externalversions/projectcalico/v3/tier.go @@ -0,0 +1,75 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Code generated by informer-gen. DO NOT EDIT. + +package v3 + +import ( + "context" + time "time" + + projectcalicov3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + clientset "github.com/projectcalico/api/pkg/client/clientset_generated/clientset" + internalinterfaces "github.com/projectcalico/api/pkg/client/informers_generated/externalversions/internalinterfaces" + v3 "github.com/projectcalico/api/pkg/client/listers_generated/projectcalico/v3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// TierInformer provides access to a shared informer and lister for +// Tiers. +type TierInformer interface { + Informer() cache.SharedIndexInformer + Lister() v3.TierLister +} + +type tierInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewTierInformer constructs a new informer for Tier type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewTierInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredTierInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredTierInformer constructs a new informer for Tier type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredTierInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ProjectcalicoV3().Tiers().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ProjectcalicoV3().Tiers().Watch(context.TODO(), options) + }, + }, + &projectcalicov3.Tier{}, + resyncPeriod, + indexers, + ) +} + +func (f *tierInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredTierInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *tierInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&projectcalicov3.Tier{}, f.defaultInformer) +} + +func (f *tierInformer) Lister() v3.TierLister { + return v3.NewTierLister(f.Informer().GetIndexer()) +} diff --git a/api/pkg/client/listers_generated/projectcalico/v3/expansion_generated.go b/api/pkg/client/listers_generated/projectcalico/v3/expansion_generated.go index 0b05d420f8e..a0cecd81d44 100644 --- a/api/pkg/client/listers_generated/projectcalico/v3/expansion_generated.go +++ b/api/pkg/client/listers_generated/projectcalico/v3/expansion_generated.go @@ -79,3 +79,7 @@ type NetworkSetNamespaceListerExpansion interface{} // ProfileListerExpansion allows custom methods to be added to // ProfileLister. type ProfileListerExpansion interface{} + +// TierListerExpansion allows custom methods to be added to +// TierLister. +type TierListerExpansion interface{} diff --git a/api/pkg/client/listers_generated/projectcalico/v3/tier.go b/api/pkg/client/listers_generated/projectcalico/v3/tier.go new file mode 100644 index 00000000000..006958ca285 --- /dev/null +++ b/api/pkg/client/listers_generated/projectcalico/v3/tier.go @@ -0,0 +1,54 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Code generated by lister-gen. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// TierLister helps list Tiers. +// All objects returned here must be treated as read-only. +type TierLister interface { + // List lists all Tiers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v3.Tier, err error) + // Get retrieves the Tier from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v3.Tier, error) + TierListerExpansion +} + +// tierLister implements the TierLister interface. +type tierLister struct { + indexer cache.Indexer +} + +// NewTierLister returns a new TierLister. +func NewTierLister(indexer cache.Indexer) TierLister { + return &tierLister{indexer: indexer} +} + +// List lists all Tiers in the indexer. +func (s *tierLister) List(selector labels.Selector) (ret []*v3.Tier, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v3.Tier)) + }) + return ret, err +} + +// Get retrieves the Tier from the index for a given name. +func (s *tierLister) Get(name string) (*v3.Tier, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v3.Resource("tier"), name) + } + return obj.(*v3.Tier), nil +} diff --git a/api/pkg/openapi/openapi_generated.go b/api/pkg/openapi/openapi_generated.go index 02c48d2f480..5717c9e3e9a 100644 --- a/api/pkg/openapi/openapi_generated.go +++ b/api/pkg/openapi/openapi_generated.go @@ -26,6 +26,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPDaemonStatus": schema_pkg_apis_projectcalico_v3_BGPDaemonStatus(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilter": schema_pkg_apis_projectcalico_v3_BGPFilter(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterList": schema_pkg_apis_projectcalico_v3_BGPFilterList(ref), + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterPrefixLengthV4": schema_pkg_apis_projectcalico_v3_BGPFilterPrefixLengthV4(ref), + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterPrefixLengthV6": schema_pkg_apis_projectcalico_v3_BGPFilterPrefixLengthV6(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterRuleV4": schema_pkg_apis_projectcalico_v3_BGPFilterRuleV4(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterRuleV6": schema_pkg_apis_projectcalico_v3_BGPFilterRuleV6(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterSpec": schema_pkg_apis_projectcalico_v3_BGPFilterSpec(ref), @@ -107,6 +109,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/projectcalico/api/pkg/apis/projectcalico/v3.ServiceExternalIPBlock": schema_pkg_apis_projectcalico_v3_ServiceExternalIPBlock(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.ServiceLoadBalancerIPBlock": schema_pkg_apis_projectcalico_v3_ServiceLoadBalancerIPBlock(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.ServiceMatch": schema_pkg_apis_projectcalico_v3_ServiceMatch(ref), + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.Tier": schema_pkg_apis_projectcalico_v3_Tier(ref), + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.TierList": schema_pkg_apis_projectcalico_v3_TierList(ref), + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.TierSpec": schema_pkg_apis_projectcalico_v3_TierSpec(ref), "github.com/projectcalico/api/pkg/apis/projectcalico/v3.WorkloadEndpointControllerConfig": schema_pkg_apis_projectcalico_v3_WorkloadEndpointControllerConfig(ref), "github.com/projectcalico/api/pkg/lib/numorstring.Port": schema_api_pkg_lib_numorstring_Port(ref), "github.com/projectcalico/api/pkg/lib/numorstring.Protocol": schema_api_pkg_lib_numorstring_Protocol(ref), @@ -128,6 +133,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/core/v1.CinderVolumeSource": schema_k8sio_api_core_v1_CinderVolumeSource(ref), "k8s.io/api/core/v1.ClaimSource": schema_k8sio_api_core_v1_ClaimSource(ref), "k8s.io/api/core/v1.ClientIPConfig": schema_k8sio_api_core_v1_ClientIPConfig(ref), + "k8s.io/api/core/v1.ClusterTrustBundleProjection": schema_k8sio_api_core_v1_ClusterTrustBundleProjection(ref), "k8s.io/api/core/v1.ComponentCondition": schema_k8sio_api_core_v1_ComponentCondition(ref), "k8s.io/api/core/v1.ComponentStatus": schema_k8sio_api_core_v1_ComponentStatus(ref), "k8s.io/api/core/v1.ComponentStatusList": schema_k8sio_api_core_v1_ComponentStatusList(ref), @@ -180,6 +186,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/core/v1.HTTPGetAction": schema_k8sio_api_core_v1_HTTPGetAction(ref), "k8s.io/api/core/v1.HTTPHeader": schema_k8sio_api_core_v1_HTTPHeader(ref), "k8s.io/api/core/v1.HostAlias": schema_k8sio_api_core_v1_HostAlias(ref), + "k8s.io/api/core/v1.HostIP": schema_k8sio_api_core_v1_HostIP(ref), "k8s.io/api/core/v1.HostPathVolumeSource": schema_k8sio_api_core_v1_HostPathVolumeSource(ref), "k8s.io/api/core/v1.ISCSIPersistentVolumeSource": schema_k8sio_api_core_v1_ISCSIPersistentVolumeSource(ref), "k8s.io/api/core/v1.ISCSIVolumeSource": schema_k8sio_api_core_v1_ISCSIVolumeSource(ref), @@ -195,6 +202,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/core/v1.LoadBalancerStatus": schema_k8sio_api_core_v1_LoadBalancerStatus(ref), "k8s.io/api/core/v1.LocalObjectReference": schema_k8sio_api_core_v1_LocalObjectReference(ref), "k8s.io/api/core/v1.LocalVolumeSource": schema_k8sio_api_core_v1_LocalVolumeSource(ref), + "k8s.io/api/core/v1.ModifyVolumeStatus": schema_k8sio_api_core_v1_ModifyVolumeStatus(ref), "k8s.io/api/core/v1.NFSVolumeSource": schema_k8sio_api_core_v1_NFSVolumeSource(ref), "k8s.io/api/core/v1.Namespace": schema_k8sio_api_core_v1_Namespace(ref), "k8s.io/api/core/v1.NamespaceCondition": schema_k8sio_api_core_v1_NamespaceCondition(ref), @@ -249,6 +257,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/core/v1.PodProxyOptions": schema_k8sio_api_core_v1_PodProxyOptions(ref), "k8s.io/api/core/v1.PodReadinessGate": schema_k8sio_api_core_v1_PodReadinessGate(ref), "k8s.io/api/core/v1.PodResourceClaim": schema_k8sio_api_core_v1_PodResourceClaim(ref), + "k8s.io/api/core/v1.PodResourceClaimStatus": schema_k8sio_api_core_v1_PodResourceClaimStatus(ref), "k8s.io/api/core/v1.PodSchedulingGate": schema_k8sio_api_core_v1_PodSchedulingGate(ref), "k8s.io/api/core/v1.PodSecurityContext": schema_k8sio_api_core_v1_PodSecurityContext(ref), "k8s.io/api/core/v1.PodSignature": schema_k8sio_api_core_v1_PodSignature(ref), @@ -306,6 +315,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/core/v1.ServiceSpec": schema_k8sio_api_core_v1_ServiceSpec(ref), "k8s.io/api/core/v1.ServiceStatus": schema_k8sio_api_core_v1_ServiceStatus(ref), "k8s.io/api/core/v1.SessionAffinityConfig": schema_k8sio_api_core_v1_SessionAffinityConfig(ref), + "k8s.io/api/core/v1.SleepAction": schema_k8sio_api_core_v1_SleepAction(ref), "k8s.io/api/core/v1.StorageOSPersistentVolumeSource": schema_k8sio_api_core_v1_StorageOSPersistentVolumeSource(ref), "k8s.io/api/core/v1.StorageOSVolumeSource": schema_k8sio_api_core_v1_StorageOSVolumeSource(ref), "k8s.io/api/core/v1.Sysctl": schema_k8sio_api_core_v1_Sysctl(ref), @@ -322,6 +332,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/core/v1.VolumeMount": schema_k8sio_api_core_v1_VolumeMount(ref), "k8s.io/api/core/v1.VolumeNodeAffinity": schema_k8sio_api_core_v1_VolumeNodeAffinity(ref), "k8s.io/api/core/v1.VolumeProjection": schema_k8sio_api_core_v1_VolumeProjection(ref), + "k8s.io/api/core/v1.VolumeResourceRequirements": schema_k8sio_api_core_v1_VolumeResourceRequirements(ref), "k8s.io/api/core/v1.VolumeSource": schema_k8sio_api_core_v1_VolumeSource(ref), "k8s.io/api/core/v1.VsphereVirtualDiskVolumeSource": schema_k8sio_api_core_v1_VsphereVirtualDiskVolumeSource(ref), "k8s.io/api/core/v1.WeightedPodAffinityTerm": schema_k8sio_api_core_v1_WeightedPodAffinityTerm(ref), @@ -352,7 +363,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/networking/v1.NetworkPolicyPeer": schema_k8sio_api_networking_v1_NetworkPolicyPeer(ref), "k8s.io/api/networking/v1.NetworkPolicyPort": schema_k8sio_api_networking_v1_NetworkPolicyPort(ref), "k8s.io/api/networking/v1.NetworkPolicySpec": schema_k8sio_api_networking_v1_NetworkPolicySpec(ref), - "k8s.io/api/networking/v1.NetworkPolicyStatus": schema_k8sio_api_networking_v1_NetworkPolicyStatus(ref), "k8s.io/api/networking/v1.ServiceBackendPort": schema_k8sio_api_networking_v1_ServiceBackendPort(ref), "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref), "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref), @@ -802,6 +812,54 @@ func schema_pkg_apis_projectcalico_v3_BGPFilterList(ref common.ReferenceCallback } } +func schema_pkg_apis_projectcalico_v3_BGPFilterPrefixLengthV4(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "min": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int32", + }, + }, + "max": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int32", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_projectcalico_v3_BGPFilterPrefixLengthV6(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "min": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int32", + }, + }, + "max": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int32", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_projectcalico_v3_BGPFilterRuleV4(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -815,6 +873,11 @@ func schema_pkg_apis_projectcalico_v3_BGPFilterRuleV4(ref common.ReferenceCallba Format: "", }, }, + "prefixLength": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterPrefixLengthV4"), + }, + }, "source": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, @@ -844,6 +907,8 @@ func schema_pkg_apis_projectcalico_v3_BGPFilterRuleV4(ref common.ReferenceCallba Required: []string{"action"}, }, }, + Dependencies: []string{ + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterPrefixLengthV4"}, } } @@ -860,6 +925,11 @@ func schema_pkg_apis_projectcalico_v3_BGPFilterRuleV6(ref common.ReferenceCallba Format: "", }, }, + "prefixLength": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterPrefixLengthV6"), + }, + }, "source": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, @@ -889,6 +959,8 @@ func schema_pkg_apis_projectcalico_v3_BGPFilterRuleV6(ref common.ReferenceCallba Required: []string{"action"}, }, }, + Dependencies: []string{ + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.BGPFilterPrefixLengthV6"}, } } @@ -1735,7 +1807,6 @@ func schema_pkg_apis_projectcalico_v3_CalicoNodeStatusStatus(ref common.Referenc "lastUpdated": { SchemaProps: spec.SchemaProps{ Description: "LastUpdated is a timestamp representing the server time when CalicoNodeStatus object last updated. It is represented in RFC3339 form and is in UTC.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -1992,8 +2063,7 @@ func schema_pkg_apis_projectcalico_v3_EndpointPort(ref common.ReferenceCallback) }, "protocol": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), }, }, "port": { @@ -2061,8 +2131,7 @@ func schema_pkg_apis_projectcalico_v3_EntityRule(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -2097,8 +2166,7 @@ func schema_pkg_apis_projectcalico_v3_EntityRule(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -2306,8 +2374,9 @@ func schema_pkg_apis_projectcalico_v3_FelixConfigurationSpec(ref common.Referenc }, "maxIpsetSize": { SchemaProps: spec.SchemaProps{ - Type: []string{"integer"}, - Format: "int32", + Description: "MaxIpsetSize is the maximum number of IP addresses that can be stored in an IP set. Not applicable if using the nftables backend.", + Type: []string{"integer"}, + Format: "int32", }, }, "iptablesBackend": { @@ -2651,8 +2720,7 @@ func schema_pkg_apis_projectcalico_v3_FelixConfigurationSpec(ref common.Referenc Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -2815,6 +2883,38 @@ func schema_pkg_apis_projectcalico_v3_FelixConfigurationSpec(ref common.Referenc Format: "", }, }, + "nftablesRefreshInterval": { + SchemaProps: spec.SchemaProps{ + Description: "NftablesRefreshInterval controls the interval at which Felix periodically refreshes the nftables rules. [Default: 90s]", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"), + }, + }, + "nftablesFilterAllowAction": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "nftablesMangleAllowAction": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "nftablesFilterDenyAction": { + SchemaProps: spec.SchemaProps{ + Description: "FilterDenyAction controls what happens to traffic that is denied by network policy. By default Calico blocks traffic with a \"drop\" action. If you want to use a \"reject\" action instead you can configure it here.", + Type: []string{"string"}, + Format: "", + }, + }, + "nftablesMarkMask": { + SchemaProps: spec.SchemaProps{ + Description: "MarkMask is the mask that Felix selects its nftables Mark bits from. Should be a 32 bit hexadecimal number with at least 8 bits set, none of which clash with any other mark bits in use on the system. [Default: 0xffff0000]", + Type: []string{"integer"}, + Format: "int64", + }, + }, "bpfEnabled": { SchemaProps: spec.SchemaProps{ Description: "BPFEnabled, if enabled Felix will use the BPF dataplane. [Default: false]", @@ -3056,6 +3156,13 @@ func schema_pkg_apis_projectcalico_v3_FelixConfigurationSpec(ref common.Referenc }, }, }, + "bpfRedirectToPeer": { + SchemaProps: spec.SchemaProps{ + Description: "BPFRedirectToPeer controls which whether it is allowed to forward straight to the peer side of the workload devices. It is allowed for any host L2 devices by default (L2Only), but it breaks TCP dump on the host side of workload device as it bypasses it on ingress. Value of Enabled also allows redirection from L3 host devices like IPIP tunnel or Wireguard directly to the peer side of the workload's device. This makes redirection faster, however, it breaks tools like tcpdump on the peer side. Use Enabled with caution. [Default: L2Only]", + Type: []string{"string"}, + Format: "", + }, + }, "routeSource": { SchemaProps: spec.SchemaProps{ Description: "RouteSource configures where Felix gets its routing information. - WorkloadIPs: use workload endpoints to construct routes. - CalicoIPAM: the default - use IPAM data to construct routes.", @@ -3332,9 +3439,16 @@ func schema_pkg_apis_projectcalico_v3_GlobalNetworkPolicySpec(ref common.Referen SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ + "tier": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the tier that this policy belongs to. If this is omitted, the default tier (name is \"default\") is assumed. The specified tier must exist in order to create security policies within the tier, the \"default\" tier is created automatically if it does not exist, this means for deployments requiring only a single Tier, the tier name may be omitted on all policy management requests.", + Type: []string{"string"}, + Format: "", + }, + }, "order": { SchemaProps: spec.SchemaProps{ - Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\".", + Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order within the same tier. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\" within the tier.", Type: []string{"number"}, Format: "double", }, @@ -3648,8 +3762,7 @@ func schema_pkg_apis_projectcalico_v3_HealthTimeoutOverride(ref common.Reference }, "timeout": { SchemaProps: spec.SchemaProps{ - Default: 0, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"), + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"), }, }, }, @@ -4609,9 +4722,16 @@ func schema_pkg_apis_projectcalico_v3_NetworkPolicySpec(ref common.ReferenceCall SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ + "tier": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the tier that this policy belongs to. If this is omitted, the default tier (name is \"default\") is assumed. The specified tier must exist in order to create security policies within the tier, the \"default\" tier is created automatically if it does not exist, this means for deployments requiring only a single Tier, the tier name may be omitted on all policy management requests.", + Type: []string{"string"}, + Format: "", + }, + }, "order": { SchemaProps: spec.SchemaProps{ - Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\".", + Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order within the same tier. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\" within the tier.", Type: []string{"number"}, Format: "double", }, @@ -5392,6 +5512,125 @@ func schema_pkg_apis_projectcalico_v3_ServiceMatch(ref common.ReferenceCallback) } } +func schema_pkg_apis_projectcalico_v3_Tier(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Tier contains a set of policies that are applied to packets. Multiple tiers may be created and each tier is applied in the order specified in the tier specification. Tier is globally-scoped (i.e. not Namespaced).", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard object's metadata.", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "Specification of the Tier.", + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/api/pkg/apis/projectcalico/v3.TierSpec"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.TierSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_projectcalico_v3_TierList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TierList contains a list of Tier resources.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/api/pkg/apis/projectcalico/v3.Tier"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/api/pkg/apis/projectcalico/v3.Tier", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_projectcalico_v3_TierSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TierSpec contains the specification for a security policy tier resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "order": { + SchemaProps: spec.SchemaProps{ + Description: "Order is an optional field that specifies the order in which the tier is applied. Tiers with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the tier will be applied last. Tiers with identical order will be applied in alphanumerical order based on the Tier \"Name\".", + Type: []string{"number"}, + Format: "double", + }, + }, + "defaultAction": { + SchemaProps: spec.SchemaProps{ + Description: "DefaultAction specifies the action applied to workloads selected by a policy in the tier, but not rule matched the workload's traffic. [Default: Deny]", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_projectcalico_v3_WorkloadEndpointControllerConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -5847,7 +6086,7 @@ func schema_k8sio_api_core_v1_CSIPersistentVolumeSource(ref common.ReferenceCall }, "nodeExpandSecretRef": { SchemaProps: spec.SchemaProps{ - Description: "nodeExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeExpandVolume call. This is a beta field which is enabled default by CSINodeExpandSecret feature gate. This field is optional, may be omitted if no secret is required. If the secret object contains more than one secret, all secrets are passed.", + Description: "nodeExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeExpandVolume call. This field is optional, may be omitted if no secret is required. If the secret object contains more than one secret, all secrets are passed.", Ref: ref("k8s.io/api/core/v1.SecretReference"), }, }, @@ -6197,7 +6436,7 @@ func schema_k8sio_api_core_v1_ClaimSource(ref common.ReferenceCallback) common.O }, "resourceClaimTemplateName": { SchemaProps: spec.SchemaProps{ - Description: "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod.\n\nThe template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The name of the ResourceClaim will be -, where is the PodResourceClaim.Name. Pod validation will reject the pod if the concatenated name is not valid for a ResourceClaim (e.g. too long).\n\nAn existing ResourceClaim with that name that is not owned by the pod will not be used for the pod to avoid using an unrelated resource by mistake. Scheduling and pod startup are then blocked until the unrelated ResourceClaim is removed.\n\nThis field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim.", + Description: "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod.\n\nThe template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, along with a generated component, will be used to form a unique name for the ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses.\n\nThis field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim.", Type: []string{"string"}, Format: "", }, @@ -6228,6 +6467,57 @@ func schema_k8sio_api_core_v1_ClientIPConfig(ref common.ReferenceCallback) commo } } +func schema_k8sio_api_core_v1_ClusterTrustBundleProjection(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ClusterTrustBundleProjection describes how to select a set of ClusterTrustBundle objects and project their contents into the pod filesystem.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Select a single ClusterTrustBundle by object name. Mutually-exclusive with signerName and labelSelector.", + Type: []string{"string"}, + Format: "", + }, + }, + "signerName": { + SchemaProps: spec.SchemaProps{ + Description: "Select all ClusterTrustBundles that match this signer name. Mutually-exclusive with name. The contents of all selected ClusterTrustBundles will be unified and deduplicated.", + Type: []string{"string"}, + Format: "", + }, + }, + "labelSelector": { + SchemaProps: spec.SchemaProps{ + Description: "Select all ClusterTrustBundles that match this label selector. Only has effect if signerName is set. Mutually-exclusive with name. If unset, interpreted as \"match nothing\". If set but empty, interpreted as \"match everything\".", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), + }, + }, + "optional": { + SchemaProps: spec.SchemaProps{ + Description: "If true, don't block pod startup if the referenced ClusterTrustBundle(s) aren't available. If using name, then the named ClusterTrustBundle is allowed not to exist. If using signerName, then the combination of signerName and labelSelector is allowed to match zero ClusterTrustBundles.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "Relative path from the volume root to write the bundle.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"path"}, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + } +} + func schema_k8sio_api_core_v1_ComponentCondition(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -6861,6 +7151,13 @@ func schema_k8sio_api_core_v1_Container(ref common.ReferenceCallback) common.Ope }, }, }, + "restartPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "RestartPolicy defines the restart behavior of individual containers in a pod. This field may only be set for init containers, and the only allowed value is \"Always\". For non-init containers or when this field is not specified, the restart behavior is defined by the Pod's restart policy and the container type. Setting the RestartPolicy as \"Always\" for the init container will have the following effect: this init container will be continually restarted on exit until all regular containers have terminated. Once all regular containers have completed, all init containers with restartPolicy \"Always\" will be shut down. This lifecycle differs from normal init containers and is often referred to as a \"sidecar\" container. Although this init container still starts in the init container sequence, it does not wait for the container to complete before proceeding to the next init container. Instead, the next init container starts immediately after this init container is started, or after any startupProbe has successfully completed.", + Type: []string{"string"}, + Format: "", + }, + }, "volumeMounts": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -7144,7 +7441,6 @@ func schema_k8sio_api_core_v1_ContainerStateRunning(ref common.ReferenceCallback "startedAt": { SchemaProps: spec.SchemaProps{ Description: "Time at which the container was last (re-)started", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -7195,14 +7491,12 @@ func schema_k8sio_api_core_v1_ContainerStateTerminated(ref common.ReferenceCallb "startedAt": { SchemaProps: spec.SchemaProps{ Description: "Time at which previous execution of the container started", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, "finishedAt": { SchemaProps: spec.SchemaProps{ Description: "Time at which the container last terminated", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -7332,8 +7626,7 @@ func schema_k8sio_api_core_v1_ContainerStatus(ref common.ReferenceCallback) comm Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -7593,7 +7886,7 @@ func schema_k8sio_api_core_v1_EndpointPort(ref common.ReferenceCallback) common. }, "appProtocol": { SchemaProps: spec.SchemaProps{ - Description: "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", + Description: "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-\n * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455\n * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", Type: []string{"string"}, Format: "", }, @@ -8022,6 +8315,13 @@ func schema_k8sio_api_core_v1_EphemeralContainer(ref common.ReferenceCallback) c }, }, }, + "restartPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Restart policy for the container to manage the restart behavior of each container within a pod. This may only be set for init containers. You cannot set this field on ephemeral containers.", + Type: []string{"string"}, + Format: "", + }, + }, "volumeMounts": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -8296,6 +8596,13 @@ func schema_k8sio_api_core_v1_EphemeralContainerCommon(ref common.ReferenceCallb }, }, }, + "restartPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Restart policy for the container to manage the restart behavior of each container within a pod. This may only be set for init containers. You cannot set this field on ephemeral containers.", + Type: []string{"string"}, + Format: "", + }, + }, "volumeMounts": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -8499,14 +8806,12 @@ func schema_k8sio_api_core_v1_Event(ref common.ReferenceCallback) common.OpenAPI "firstTimestamp": { SchemaProps: spec.SchemaProps{ Description: "The time at which the event was first recorded. (Time of server receipt is in TypeMeta.)", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, "lastTimestamp": { SchemaProps: spec.SchemaProps{ Description: "The time at which the most recent occurrence of this event was recorded.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -8527,7 +8832,6 @@ func schema_k8sio_api_core_v1_Event(ref common.ReferenceCallback) common.OpenAPI "eventTime": { SchemaProps: spec.SchemaProps{ Description: "Time when this Event was first observed.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime"), }, }, @@ -8643,7 +8947,6 @@ func schema_k8sio_api_core_v1_EventSeries(ref common.ReferenceCallback) common.O "lastObservedTime": { SchemaProps: spec.SchemaProps{ Description: "Time of the last occurrence observed", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime"), }, }, @@ -9127,7 +9430,6 @@ func schema_k8sio_api_core_v1_HTTPGetAction(ref common.ReferenceCallback) common "port": { SchemaProps: spec.SchemaProps{ Description: "Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/util/intstr.IntOrString"), }, }, @@ -9234,6 +9536,26 @@ func schema_k8sio_api_core_v1_HostAlias(ref common.ReferenceCallback) common.Ope } } +func schema_k8sio_api_core_v1_HostIP(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "HostIP represents a single IP address allocated to the host.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ip": { + SchemaProps: spec.SchemaProps{ + Description: "IP is the IP address assigned to the host", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_k8sio_api_core_v1_HostPathVolumeSource(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -9559,11 +9881,17 @@ func schema_k8sio_api_core_v1_LifecycleHandler(ref common.ReferenceCallback) com Ref: ref("k8s.io/api/core/v1.TCPSocketAction"), }, }, + "sleep": { + SchemaProps: spec.SchemaProps{ + Description: "Sleep represents the duration that the container should sleep before being terminated.", + Ref: ref("k8s.io/api/core/v1.SleepAction"), + }, + }, }, }, }, Dependencies: []string{ - "k8s.io/api/core/v1.ExecAction", "k8s.io/api/core/v1.HTTPGetAction", "k8s.io/api/core/v1.TCPSocketAction"}, + "k8s.io/api/core/v1.ExecAction", "k8s.io/api/core/v1.HTTPGetAction", "k8s.io/api/core/v1.SleepAction", "k8s.io/api/core/v1.TCPSocketAction"}, } } @@ -9633,8 +9961,7 @@ func schema_k8sio_api_core_v1_LimitRangeItem(ref common.ReferenceCallback) commo Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -9648,8 +9975,7 @@ func schema_k8sio_api_core_v1_LimitRangeItem(ref common.ReferenceCallback) commo Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -9663,8 +9989,7 @@ func schema_k8sio_api_core_v1_LimitRangeItem(ref common.ReferenceCallback) commo Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -9678,8 +10003,7 @@ func schema_k8sio_api_core_v1_LimitRangeItem(ref common.ReferenceCallback) commo Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -9693,8 +10017,7 @@ func schema_k8sio_api_core_v1_LimitRangeItem(ref common.ReferenceCallback) commo Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -9825,8 +10148,7 @@ func schema_k8sio_api_core_v1_List(ref common.ReferenceCallback) common.OpenAPID Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, }, @@ -9862,6 +10184,13 @@ func schema_k8sio_api_core_v1_LoadBalancerIngress(ref common.ReferenceCallback) Format: "", }, }, + "ipMode": { + SchemaProps: spec.SchemaProps{ + Description: "IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified. Setting this to \"VIP\" indicates that traffic is delivered to the node with the destination set to the load-balancer's IP and port. Setting this to \"Proxy\" indicates that traffic is delivered to the node or pod with the destination set to the node's IP and node port or the pod's IP and port. Service implementations may use this information to adjust traffic routing.", + Type: []string{"string"}, + Format: "", + }, + }, "ports": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -9972,6 +10301,36 @@ func schema_k8sio_api_core_v1_LocalVolumeSource(ref common.ReferenceCallback) co } } +func schema_k8sio_api_core_v1_ModifyVolumeStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ModifyVolumeStatus represents the status object of ControllerModifyVolume operation", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "targetVolumeAttributesClassName": { + SchemaProps: spec.SchemaProps{ + Description: "targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled", + Type: []string{"string"}, + Format: "", + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Description: "status is the status of the ControllerModifyVolume operation. It can be in any of following states:\n - Pending\n Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\n the specified VolumeAttributesClass not existing.\n - InProgress\n InProgress indicates that the volume is being modified.\n - Infeasible\n Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass needs to be specified.\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately.\n\nPossible enum values:\n - `\"InProgress\"` InProgress indicates that the volume is being modified\n - `\"Infeasible\"` Infeasible indicates that the request has been rejected as invalid by the CSI driver. To resolve the error, a valid VolumeAttributesClass needs to be specified\n - `\"Pending\"` Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as the specified VolumeAttributesClass not existing", + Default: "", + Type: []string{"string"}, + Format: "", + Enum: []interface{}{"InProgress", "Infeasible", "Pending"}, + }, + }, + }, + Required: []string{"status"}, + }, + }, + } +} + func schema_k8sio_api_core_v1_NFSVolumeSource(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -10084,8 +10443,7 @@ func schema_k8sio_api_core_v1_NamespaceCondition(ref common.ReferenceCallback) c }, "lastTransitionTime": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, "reason": { @@ -10372,14 +10730,12 @@ func schema_k8sio_api_core_v1_NodeCondition(ref common.ReferenceCallback) common "lastHeartbeatTime": { SchemaProps: spec.SchemaProps{ Description: "Last time we got an update on a given condition.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, "lastTransitionTime": { SchemaProps: spec.SchemaProps{ Description: "Last time the condition transit from one status to another.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -10589,8 +10945,7 @@ func schema_k8sio_api_core_v1_NodeResources(ref common.ReferenceCallback) common Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -10832,8 +11187,7 @@ func schema_k8sio_api_core_v1_NodeStatus(ref common.ReferenceCallback) common.Op Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -10847,8 +11201,7 @@ func schema_k8sio_api_core_v1_NodeStatus(ref common.ReferenceCallback) common.Op Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -11292,14 +11645,12 @@ func schema_k8sio_api_core_v1_PersistentVolumeClaimCondition(ref common.Referenc "lastProbeTime": { SchemaProps: spec.SchemaProps{ Description: "lastProbeTime is the time we probed the condition.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, "lastTransitionTime": { SchemaProps: spec.SchemaProps{ Description: "lastTransitionTime is the time the condition transitioned from one status to another.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -11409,7 +11760,7 @@ func schema_k8sio_api_core_v1_PersistentVolumeClaimSpec(ref common.ReferenceCall SchemaProps: spec.SchemaProps{ Description: "resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources", Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.ResourceRequirements"), + Ref: ref("k8s.io/api/core/v1.VolumeResourceRequirements"), }, }, "volumeName": { @@ -11446,11 +11797,18 @@ func schema_k8sio_api_core_v1_PersistentVolumeClaimSpec(ref common.ReferenceCall Ref: ref("k8s.io/api/core/v1.TypedObjectReference"), }, }, + "volumeAttributesClassName": { + SchemaProps: spec.SchemaProps{ + Description: "volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. If specified, the CSI driver will create or update the volume with the attributes defined in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass will be applied to the claim but it's not allowed to reset this field to empty string once it is set. If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass will be set by the persistentvolume controller if it exists. If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, Dependencies: []string{ - "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.TypedLocalObjectReference", "k8s.io/api/core/v1.TypedObjectReference", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "k8s.io/api/core/v1.TypedLocalObjectReference", "k8s.io/api/core/v1.TypedObjectReference", "k8s.io/api/core/v1.VolumeResourceRequirements", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, } } @@ -11492,8 +11850,7 @@ func schema_k8sio_api_core_v1_PersistentVolumeClaimStatus(ref common.ReferenceCa Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -11507,46 +11864,71 @@ func schema_k8sio_api_core_v1_PersistentVolumeClaimStatus(ref common.ReferenceCa }, }, SchemaProps: spec.SchemaProps{ - Description: "conditions is the current Condition of persistent volume claim. If underlying persistent volume is being resized then the Condition will be set to 'ResizeStarted'.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ + Description: "conditions is the current Condition of persistent volume claim. If underlying persistent volume is being resized then the Condition will be set to 'ResizeStarted'.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.PersistentVolumeClaimCondition"), + }, + }, + }, + }, + }, + "allocatedResources": { + SchemaProps: spec.SchemaProps{ + Description: "allocatedResources tracks the resources allocated to a PVC including its capacity. Key names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered reserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation is requested. For storage quota, the larger value from allocatedResources and PVC.spec.resources is used. If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation. If a volume expansion capacity request is lowered, allocatedResources is only lowered if there are no expansion operations in progress and if the actual volume capacity is equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName should ignore the update for the purpose it was designed. For example - a controller that only is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid resources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.PersistentVolumeClaimCondition"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, }, }, - "allocatedResources": { + "allocatedResourceStatuses": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-map-type": "granular", + }, + }, SchemaProps: spec.SchemaProps{ - Description: "allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may be larger than the actual capacity when a volume expansion operation is requested. For storage quota, the larger value from allocatedResources and PVC.spec.resources is used. If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation. If a volume expansion capacity request is lowered, allocatedResources is only lowered if there are no expansion operations in progress and if the actual volume capacity is equal or lower than the requested capacity. This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.", + Description: "allocatedResourceStatuses stores status of resource being resized for the given PVC. Key names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered reserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus should ignore the update for the purpose it was designed. For example - a controller that only is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid resources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.", Type: []string{"object"}, AdditionalProperties: &spec.SchemaOrBool{ Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Default: "", + Type: []string{"string"}, + Format: "", }, }, }, }, }, - "resizeStatus": { + "currentVolumeAttributesClassName": { SchemaProps: spec.SchemaProps{ - Description: "resizeStatus stores status of resize operation. ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty string by resize controller or kubelet. This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\n\nPossible enum values:\n - `\"\"` When expansion is complete, the empty string is set by resize controller or kubelet.\n - `\"ControllerExpansionFailed\"` State set when expansion has failed in resize controller with a terminal error. Transient errors such as timeout should not set this status and should leave ResizeStatus unmodified, so as resize controller can resume the volume expansion.\n - `\"ControllerExpansionInProgress\"` State set when resize controller starts expanding the volume in control-plane\n - `\"NodeExpansionFailed\"` State set when expansion has failed in kubelet with a terminal error. Transient errors don't set NodeExpansionFailed.\n - `\"NodeExpansionInProgress\"` State set when kubelet starts expanding the volume.\n - `\"NodeExpansionPending\"` State set when resize controller has finished expanding the volume but further expansion is needed on the node.", + Description: "currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim This is an alpha field and requires enabling VolumeAttributesClass feature.", Type: []string{"string"}, Format: "", - Enum: []interface{}{"", "ControllerExpansionFailed", "ControllerExpansionInProgress", "NodeExpansionFailed", "NodeExpansionInProgress", "NodeExpansionPending"}, + }, + }, + "modifyVolumeStatus": { + SchemaProps: spec.SchemaProps{ + Description: "ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. When this is unset, there is no ModifyVolume operation being attempted. This is an alpha field and requires enabling VolumeAttributesClass feature.", + Ref: ref("k8s.io/api/core/v1.ModifyVolumeStatus"), }, }, }, }, }, Dependencies: []string{ - "k8s.io/api/core/v1.PersistentVolumeClaimCondition", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, + "k8s.io/api/core/v1.ModifyVolumeStatus", "k8s.io/api/core/v1.PersistentVolumeClaimCondition", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, } } @@ -11822,8 +12204,7 @@ func schema_k8sio_api_core_v1_PersistentVolumeSpec(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -12031,6 +12412,13 @@ func schema_k8sio_api_core_v1_PersistentVolumeSpec(ref common.ReferenceCallback) Ref: ref("k8s.io/api/core/v1.VolumeNodeAffinity"), }, }, + "volumeAttributesClassName": { + SchemaProps: spec.SchemaProps{ + Description: "Name of VolumeAttributesClass to which this persistent volume belongs. Empty value is not allowed. When this field is not set, it indicates that this volume does not belong to any VolumeAttributesClass. This field is mutable and can be changed by the CSI driver after a volume has been updated successfully to a new class. For an unbound PersistentVolume, the volumeAttributesClassName will be matched with unbound PersistentVolumeClaims during the binding process. This is an alpha field and requires enabling VolumeAttributesClass feature.", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, @@ -12068,9 +12456,17 @@ func schema_k8sio_api_core_v1_PersistentVolumeStatus(ref common.ReferenceCallbac Format: "", }, }, + "lastPhaseTransitionTime": { + SchemaProps: spec.SchemaProps{ + Description: "lastPhaseTransitionTime is the time the phase transitioned from one to another and automatically resets to current time everytime a volume phase transitions. This is a beta field and requires the PersistentVolumeLastPhaseTransitionTime feature to be enabled (enabled by default).", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), + }, + }, }, }, }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -12205,7 +12601,7 @@ func schema_k8sio_api_core_v1_PodAffinityTerm(ref common.ReferenceCallback) comm Properties: map[string]spec.Schema{ "labelSelector": { SchemaProps: spec.SchemaProps{ - Description: "A label query over a set of resources, in this case pods.", + Description: "A label query over a set of resources, in this case pods. If it's null, this PodAffinityTerm matches with no Pods.", Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), }, }, @@ -12238,6 +12634,46 @@ func schema_k8sio_api_core_v1_PodAffinityTerm(ref common.ReferenceCallback) comm Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), }, }, + "matchLabelKeys": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "mismatchLabelKeys": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, Required: []string{"topologyKey"}, }, @@ -12378,14 +12814,12 @@ func schema_k8sio_api_core_v1_PodCondition(ref common.ReferenceCallback) common. "lastProbeTime": { SchemaProps: spec.SchemaProps{ Description: "Last time we probed the condition.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, "lastTransitionTime": { SchemaProps: spec.SchemaProps{ Description: "Last time the condition transitioned from one status to another.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -12579,12 +13013,12 @@ func schema_k8sio_api_core_v1_PodIP(ref common.ReferenceCallback) common.OpenAPI return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "IP address information for entries in the (plural) PodIPs field. Each entry includes:\n\n\tIP: An IP address allocated to the pod. Routable at least within the cluster.", + Description: "PodIP represents a single IP address allocated to the pod.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "ip": { SchemaProps: spec.SchemaProps{ - Description: "ip is an IP address (IPv4 or IPv6) assigned to the pod", + Description: "IP is the IP address assigned to the pod", Type: []string{"string"}, Format: "", }, @@ -12888,6 +13322,35 @@ func schema_k8sio_api_core_v1_PodResourceClaim(ref common.ReferenceCallback) com } } +func schema_k8sio_api_core_v1_PodResourceClaimStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PodResourceClaimStatus is stored in the PodStatus for each PodResourceClaim which references a ResourceClaimTemplate. It stores the generated name for the corresponding ResourceClaim.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name uniquely identifies this resource claim inside the pod. This must match the name of an entry in pod.spec.resourceClaims, which implies that the string must be a DNS_LABEL.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "resourceClaimName": { + SchemaProps: spec.SchemaProps{ + Description: "ResourceClaimName is the name of the ResourceClaim that was generated for the Pod in the namespace of the Pod. It this is unset, then generating a ResourceClaim was not necessary. The pod.spec.resourceClaims entry can be ignored in this case.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + } +} + func schema_k8sio_api_core_v1_PodSchedulingGate(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -13374,8 +13837,7 @@ func schema_k8sio_api_core_v1_PodSpec(ref common.ReferenceCallback) common.OpenA Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -13541,14 +14003,35 @@ func schema_k8sio_api_core_v1_PodStatus(ref common.ReferenceCallback) common.Ope }, "hostIP": { SchemaProps: spec.SchemaProps{ - Description: "IP address of the host to which the pod is assigned. Empty if not yet scheduled.", + Description: "hostIP holds the IP address of the host to which the pod is assigned. Empty if the pod has not started yet. A pod can be assigned to a node that has a problem in kubelet which in turns mean that HostIP will not be updated even if there is a node is assigned to pod", Type: []string{"string"}, Format: "", }, }, + "hostIPs": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "ip", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "hostIPs holds the IP addresses allocated to the host. If this field is specified, the first entry must match the hostIP field. This list is empty if the pod has not started yet. A pod can be assigned to a node that has a problem in kubelet which in turns means that HostIPs will not be updated even if there is a node is assigned to this pod.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.HostIP"), + }, + }, + }, + }, + }, "podIP": { SchemaProps: spec.SchemaProps{ - Description: "IP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.", + Description: "podIP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.", Type: []string{"string"}, Format: "", }, @@ -13636,11 +14119,35 @@ func schema_k8sio_api_core_v1_PodStatus(ref common.ReferenceCallback) common.Ope Format: "", }, }, + "resourceClaimStatuses": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "name", + }, + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge,retainKeys", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Status of resource claims.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.PodResourceClaimStatus"), + }, + }, + }, + }, + }, }, }, }, Dependencies: []string{ - "k8s.io/api/core/v1.ContainerStatus", "k8s.io/api/core/v1.PodCondition", "k8s.io/api/core/v1.PodIP", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "k8s.io/api/core/v1.ContainerStatus", "k8s.io/api/core/v1.HostIP", "k8s.io/api/core/v1.PodCondition", "k8s.io/api/core/v1.PodIP", "k8s.io/api/core/v1.PodResourceClaimStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -13900,7 +14407,6 @@ func schema_k8sio_api_core_v1_PreferAvoidPodsEntry(ref common.ReferenceCallback) "evictionTime": { SchemaProps: spec.SchemaProps{ Description: "Time at which this entry was added to the list.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -14460,7 +14966,6 @@ func schema_k8sio_api_core_v1_ReplicationControllerCondition(ref common.Referenc "lastTransitionTime": { SchemaProps: spec.SchemaProps{ Description: "The last time the condition transitioned from one status to another.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -14713,7 +15218,6 @@ func schema_k8sio_api_core_v1_ResourceFieldSelector(ref common.ReferenceCallback "divisor": { SchemaProps: spec.SchemaProps{ Description: "Specifies the output format of the exposed resources, defaults to \"1\"", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, @@ -14847,8 +15351,7 @@ func schema_k8sio_api_core_v1_ResourceQuotaSpec(ref common.ReferenceCallback) co Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -14898,8 +15401,7 @@ func schema_k8sio_api_core_v1_ResourceQuotaStatus(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -14913,8 +15415,7 @@ func schema_k8sio_api_core_v1_ResourceQuotaStatus(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -14943,8 +15444,7 @@ func schema_k8sio_api_core_v1_ResourceRequirements(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -14958,8 +15458,7 @@ func schema_k8sio_api_core_v1_ResourceRequirements(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, }, @@ -15309,7 +15808,7 @@ func schema_k8sio_api_core_v1_SeccompProfile(ref common.ReferenceCallback) commo }, "localhostProfile": { SchemaProps: spec.SchemaProps{ - Description: "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is \"Localhost\".", + Description: "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must be set if type is \"Localhost\". Must NOT be set for any other type.", Type: []string{"string"}, Format: "", }, @@ -16073,7 +16572,7 @@ func schema_k8sio_api_core_v1_ServicePort(ref common.ReferenceCallback) common.O }, "appProtocol": { SchemaProps: spec.SchemaProps{ - Description: "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + Description: "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-\n * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455\n * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", Type: []string{"string"}, Format: "", }, @@ -16089,7 +16588,6 @@ func schema_k8sio_api_core_v1_ServicePort(ref common.ReferenceCallback) common.O "targetPort": { SchemaProps: spec.SchemaProps{ Description: "Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/util/intstr.IntOrString"), }, }, @@ -16256,7 +16754,7 @@ func schema_k8sio_api_core_v1_ServiceSpec(ref common.ReferenceCallback) common.O }, "loadBalancerIP": { SchemaProps: spec.SchemaProps{ - Description: "Only applies to Service Type: LoadBalancer. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature. Deprecated: This field was under-specified and its meaning varies across implementations, and it cannot support dual-stack. As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available. This field may be removed in a future API version.", + Description: "Only applies to Service Type: LoadBalancer. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature. Deprecated: This field was under-specified and its meaning varies across implementations. Using it is non-portable and it may not support dual-stack. Users are encouraged to use implementation-specific annotations when available.", Type: []string{"string"}, Format: "", }, @@ -16436,6 +16934,28 @@ func schema_k8sio_api_core_v1_SessionAffinityConfig(ref common.ReferenceCallback } } +func schema_k8sio_api_core_v1_SleepAction(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SleepAction describes a \"sleep\" action.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "seconds": { + SchemaProps: spec.SchemaProps{ + Description: "Seconds is the number of seconds to sleep.", + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + Required: []string{"seconds"}, + }, + }, + } +} + func schema_k8sio_api_core_v1_StorageOSPersistentVolumeSource(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -16574,7 +17094,6 @@ func schema_k8sio_api_core_v1_TCPSocketAction(ref common.ReferenceCallback) comm "port": { SchemaProps: spec.SchemaProps{ Description: "Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/util/intstr.IntOrString"), }, }, @@ -17275,11 +17794,60 @@ func schema_k8sio_api_core_v1_VolumeProjection(ref common.ReferenceCallback) com Ref: ref("k8s.io/api/core/v1.ServiceAccountTokenProjection"), }, }, + "clusterTrustBundle": { + SchemaProps: spec.SchemaProps{ + Description: "ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field of ClusterTrustBundle objects in an auto-updating file.\n\nAlpha, gated by the ClusterTrustBundleProjection feature gate.\n\nClusterTrustBundle objects can either be selected by name, or by the combination of signer name and a label selector.\n\nKubelet performs aggressive normalization of the PEM contents written into the pod filesystem. Esoteric PEM features such as inter-block comments and block headers are stripped. Certificates are deduplicated. The ordering of certificates within the file is arbitrary, and Kubelet may change the order over time.", + Ref: ref("k8s.io/api/core/v1.ClusterTrustBundleProjection"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/api/core/v1.ClusterTrustBundleProjection", "k8s.io/api/core/v1.ConfigMapProjection", "k8s.io/api/core/v1.DownwardAPIProjection", "k8s.io/api/core/v1.SecretProjection", "k8s.io/api/core/v1.ServiceAccountTokenProjection"}, + } +} + +func schema_k8sio_api_core_v1_VolumeResourceRequirements(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "VolumeResourceRequirements describes the storage resource requirements for a volume.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "limits": { + SchemaProps: spec.SchemaProps{ + Description: "Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + }, + }, + }, + "requests": { + SchemaProps: spec.SchemaProps{ + Description: "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + }, + }, + }, }, }, }, Dependencies: []string{ - "k8s.io/api/core/v1.ConfigMapProjection", "k8s.io/api/core/v1.DownwardAPIProjection", "k8s.io/api/core/v1.SecretProjection", "k8s.io/api/core/v1.ServiceAccountTokenProjection"}, + "k8s.io/apimachinery/pkg/api/resource.Quantity"}, } } @@ -17576,7 +18144,7 @@ func schema_k8sio_api_core_v1_WindowsSecurityContextOptions(ref common.Reference }, "hostProcess": { SchemaProps: spec.SchemaProps{ - Description: "HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true.", + Description: "HostProcess determines if a container should be run as a 'Host Process' container. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true.", Type: []string{"boolean"}, Format: "", }, @@ -18354,18 +18922,11 @@ func schema_k8sio_api_networking_v1_NetworkPolicy(ref common.ReferenceCallback) Ref: ref("k8s.io/api/networking/v1.NetworkPolicySpec"), }, }, - "status": { - SchemaProps: spec.SchemaProps{ - Description: "status represents the current state of the NetworkPolicy. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/networking/v1.NetworkPolicyStatus"), - }, - }, }, }, }, Dependencies: []string{ - "k8s.io/api/networking/v1.NetworkPolicySpec", "k8s.io/api/networking/v1.NetworkPolicyStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "k8s.io/api/networking/v1.NetworkPolicySpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -18641,45 +19202,6 @@ func schema_k8sio_api_networking_v1_NetworkPolicySpec(ref common.ReferenceCallba } } -func schema_k8sio_api_networking_v1_NetworkPolicyStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "NetworkPolicyStatus describes the current state of the NetworkPolicy.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "conditions": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-map-keys": []interface{}{ - "type", - }, - "x-kubernetes-list-type": "map", - "x-kubernetes-patch-merge-key": "type", - "x-kubernetes-patch-strategy": "merge", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. Current service state", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, - } -} - func schema_k8sio_api_networking_v1_ServiceBackendPort(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -19139,7 +19661,6 @@ func schema_pkg_apis_meta_v1_Condition(ref common.ReferenceCallback) common.Open "lastTransitionTime": { SchemaProps: spec.SchemaProps{ Description: "lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -19623,12 +20144,6 @@ func schema_pkg_apis_meta_v1_LabelSelectorRequirement(ref common.ReferenceCallba Type: []string{"object"}, Properties: map[string]spec.Schema{ "key": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-patch-merge-key": "key", - "x-kubernetes-patch-strategy": "merge", - }, - }, SchemaProps: spec.SchemaProps{ Description: "key is the label key that the selector applies to.", Default: "", @@ -19701,8 +20216,7 @@ func schema_pkg_apis_meta_v1_List(ref common.ReferenceCallback) common.OpenAPIDe Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, }, @@ -19988,7 +20502,6 @@ func schema_pkg_apis_meta_v1_ObjectMeta(ref common.ReferenceCallback) common.Ope "creationTimestamp": { SchemaProps: spec.SchemaProps{ Description: "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, @@ -20770,7 +21283,6 @@ func schema_pkg_apis_meta_v1_TableRow(ref common.ReferenceCallback) common.OpenA "object": { SchemaProps: spec.SchemaProps{ Description: "This field contains the requested additional information about each object based on the includeObject policy when requesting the Table. If \"None\", this field is empty, if \"Object\" this will be the default serialization of the object for the current API version, and if \"Metadata\" (the default) will contain the object metadata. Check the returned kind and apiVersion of the object before parsing. The media type of the object will always match the enclosing list - if this as a JSON table, these will be JSON encoded objects.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, @@ -20969,7 +21481,6 @@ func schema_pkg_apis_meta_v1_WatchEvent(ref common.ReferenceCallback) common.Ope "object": { SchemaProps: spec.SchemaProps{ Description: "Object is:\n * If Type is Added or Modified: the new state of the object.\n * If Type is Deleted: the state of the object immediately before deletion.\n * If Type is Error: *Status is recommended; other types may make sense\n depending on context.", - Default: map[string]interface{}{}, Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, diff --git a/apiserver/cmd/apiserver/apiserver.go b/apiserver/cmd/apiserver/apiserver.go index a7551ee34a7..be11340376b 100644 --- a/apiserver/cmd/apiserver/apiserver.go +++ b/apiserver/cmd/apiserver/apiserver.go @@ -39,7 +39,9 @@ func main() { // The ConsistentListFromCache feature gate requires our resourceStore // to support method RequestWatchProgress, which it does not. Force-disable // the gate. - err := feature.DefaultMutableFeatureGate.SetFromMap(map[string]bool{string(features.ConsistentListFromCache): false}) + err := feature.DefaultMutableFeatureGate.SetFromMap(map[string]bool{ + string(features.ConsistentListFromCache): false, + }) if err != nil { klog.Errorf("Error setting feature gates: %v.", err) logs.FlushLogs() diff --git a/apiserver/cmd/apiserver/server/options.go b/apiserver/cmd/apiserver/server/options.go index 1359a03ea4a..405ff8ef51b 100644 --- a/apiserver/cmd/apiserver/server/options.go +++ b/apiserver/cmd/apiserver/server/options.go @@ -118,6 +118,12 @@ func (o *CalicoServerOptions) Config() (*apiserver.Config, error) { return nil, err } + // We now build the APIServer against >= k8s v1.29. + // FlowControl API resources graduated to v1 in this version, + // so if we run this APIServer on a backlevel (.* + // + // Note that if we do not have cluster-wide access for the tier then we'll need to check per-namespace, so we track + // Tiers that did not match cluster scoped. + var tiersNoClusterMatch []string + if res.isTieredPolicy() { + log.Debug("Check cluster-scoped tiered-policy in each gettable tier") + + for _, tier := range u.getGettableTiers() { + record.Name = tier.Name + ".*" + if rbac_auth.RulesAllow(record, u.getClusterRules()...) { + log.Debugf("Rules allow cluster-scoped policy in tier(%s)", tier) + match.Tier = tier.Name + matches = append(matches, match) + } else { + log.Debugf("Rules do not allow cluster-scoped policy in tier(%s)", tier) + tiersNoClusterMatch = append(tiersNoClusterMatch, tier.Name) + } + } + + if tiersNoClusterMatch == nil { + // If every tier was specified individually and matched cluster-wide, then there is no point in checking + // per-namespace. + log.Debug("All Tiers individually matched cluster-wide") + return matches + } + } + + // If the resource is not namespaced then no more checks. + if !res.Namespaced { + log.Debug("Resource is not namespaced, so nothing left to check") + return matches + } + + // Now check namespaced matches. We limit this just to the Namespaces that the user has rules for. + for namespace, rules := range u.getNamespacedRules() { + log.Debugf("Processing rules for namespace %s", namespace) + match.Namespace = namespace + match.Tier = "" + record.Namespace = namespace + record.Name = "" + if rbac_auth.RulesAllow(record, rules...) { + // The user is authorized for full wildcarded names for the resource type in this namespace + // - If this is a tiered policy then expand by tier. + // - Otherwise, include a single wildcarded name result. + if !res.isTieredPolicy() { + // This is not a tiered policy so include the match unchanged. + log.Debug("Add namespaced match for non-tiered policy") + matches = append(matches, match) + } else { + // This is a tiered policy, expand the results by gettable tier. + log.Debug("Add namespaced match for all Tiers for tiered policy") + for _, tier := range tiersNoClusterMatch { + log.Debugf("Add namespaced match for tiered policy: tier=%s", tier) + match.Tier = tier + matches = append(matches, match) + } + } + + // We matched wildcard name, so go to next namespace. + continue + } + + // Did not match wildcarded tier, so try individual Tiers (that were not matched cluster-wide). + // [note: tiersNoClusterMatch will be nil if this is not a tiered policy resource] + for _, tier := range tiersNoClusterMatch { + record.Name = tier + ".*" + if rbac_auth.RulesAllow(record, rules...) { + log.Debugf("Add namespaced match for tiered policy: tier=%s", tier) + match.Tier = tier + matches = append(matches, match) + } + } + } + + return matches +} + +// canGetAllTiers determines whether the user is able to get all Tiers. +func (u *userCalculator) canGetAllTiers() bool { + if u.canGetAllTiersVal == nil { + allTiers := rbac_auth.RulesAllow(authorizer.AttributesRecord{ + Verb: string(VerbGet), + APIGroup: v3.Group, + Resource: resourceTiers, + Name: "", + ResourceRequest: true, + }, u.getClusterRules()...) + u.canGetAllTiersVal = &allTiers + } + + return *u.canGetAllTiersVal +} + +// getAllTiers returns the current set of configured Tiers. +func (u *userCalculator) getAllTiers() []types.NamespacedName { + if u.allTiers == nil { + if tiers, err := u.calculator.calicoResourceLister.ListTiers(); err != nil { + log.WithError(err).Debug("Failed to list Tiers") + u.errors = append(u.errors, err) + u.allTiers = make([]types.NamespacedName, 0) + } else { + for _, tier := range tiers { + u.allTiers = append(u.allTiers, types.NamespacedName{Name: tier.Name}) + } + } + log.Debugf("getAllTiers returns %v", u.allTiers) + } + return u.allTiers +} + +// getGettableTiers determines which Tiers the user is able to get. +func (u *userCalculator) getGettableTiers() []types.NamespacedName { + if u.gettableTiers == nil { + for _, tier := range u.getAllTiers() { + if u.canGetAllTiers() || rbac_auth.RulesAllow(authorizer.AttributesRecord{ + Verb: string(VerbGet), + APIGroup: v3.Group, + Resource: resourceTiers, + Name: tier.Name, + ResourceRequest: true, + }, u.getClusterRules()...) { + u.gettableTiers = append(u.gettableTiers, tier) + } + } + log.Debugf("getGettableTiers returns %v", u.gettableTiers) + } + + return u.gettableTiers +} + +// expandResourceByName checks authorization of a verb on a specific resource type for individual +// names. This is only used in certain cases because expanding by name could be an expensive operation. +func (u *userCalculator) expandResourceByName(names []types.NamespacedName, verb Verb, res apiResource) (rs []types.NamespacedName) { + for _, name := range names { + log.Debugf("check RBAC for resource %v", name) + rules := u.getClusterRules() + if name.Namespace != "" { + log.Debugf("Include namespace rules for %v", name) + rules = append(rules, u.getNamespacedRules()[name.Namespace]...) + } + if rbac_auth.RulesAllow(authorizer.AttributesRecord{ + Verb: string(verb), + APIGroup: res.APIGroup, + Resource: res.Resource, + Name: name.Name, + Namespace: name.Namespace, + ResourceRequest: true, + }, rules...) { + rs = append(rs, name) + } + + } + + log.Debugf("expandClusterResourceByName returns %v", rs) + return rs +} + +// canGetAllNamespaces determines whether the user is able to get all Namespaces. +func (u *userCalculator) canGetAllNamespaces() bool { + if u.canGetAllNamespacesVal == nil { + allNamespaces := rbac_auth.RulesAllow(authorizer.AttributesRecord{ + Verb: string(VerbGet), + APIGroup: "", + Resource: resourceNamespaces, + Name: "", + ResourceRequest: true, + }, u.getClusterRules()...) + u.canGetAllNamespacesVal = &allNamespaces + log.Debugf("canGetAllNamespaces returns %v", u.canGetAllNamespacesVal) + } + + return *u.canGetAllNamespacesVal +} + +// getAllNamespaces returns the current set of configured Namespaces. +func (u *userCalculator) getAllNamespaces() []types.NamespacedName { + if u.allNamespaces == nil { + if namespaces, err := u.calculator.namespaceLister.ListNamespaces(); err != nil { + log.WithError(err).Debug("Failed to list Namespaces") + u.errors = append(u.errors, err) + u.allNamespaces = make([]types.NamespacedName, 0) + } else { + for _, namespace := range namespaces { + u.allNamespaces = append(u.allNamespaces, types.NamespacedName{Name: namespace.Name}) + } + } + log.Debugf("getAllNamespaces returns %v", u.allNamespaces) + } + + return u.allNamespaces +} + +// getGettableNamespaces determines which Namespaces the user is able to get. +func (u *userCalculator) getGettableNamespaces() []types.NamespacedName { + if u.gettableNamespaces == nil { + for _, namespace := range u.getAllNamespaces() { + if u.canGetAllNamespaces() || rbac_auth.RulesAllow(authorizer.AttributesRecord{ + Verb: string(VerbGet), + APIGroup: v3.Group, + Resource: resourceNamespaces, + Name: namespace.Name, + ResourceRequest: true, + }, u.getClusterRules()...) { + u.gettableNamespaces = append(u.gettableNamespaces, namespace) + } + } + log.Debugf("getGettableNamespaces returns %v", u.gettableNamespaces) + } + + return u.gettableNamespaces +} + +// getClusterRules returns the cluster rules that apply to the user. +func (u *userCalculator) getClusterRules() []rbacv1.PolicyRule { + if u.clusterRules == nil { + // ClusterRuleResolver returns aggregated errors when matching rules + rules, errors := u.calculator.clusterRuleResolver.RulesFor(u.user, "") + if errors != nil { + log.WithError(errors).Debug("Failed to list cluster-wide rules for user") + // Filter out NotFound error for any missing cluster role to match the k8s API + curatedError := utilerrors.FilterOut(errors, func(err error) bool { + return k8serrors.IsNotFound(err) + }) + if curatedError != nil { + u.errors = append(u.errors, curatedError) + } + } + + // Set matched rules + if rules != nil { + u.clusterRules = rules + } else { + u.clusterRules = make([]rbacv1.PolicyRule, 0) + } + + log.Debugf("getClusterRules returns %v", u.clusterRules) + } + + return u.clusterRules +} + +// getNamespacedRules returns the namespaced rules that apply to the user. +func (u *userCalculator) getNamespacedRules() map[string][]rbacv1.PolicyRule { + if u.namespacedRules == nil { + u.namespacedRules = make(map[string][]rbacv1.PolicyRule) + if namespaces, err := u.calculator.namespaceLister.ListNamespaces(); err != nil { + log.WithError(err).Debug("Failed to list namespaced rules for user") + u.errors = append(u.errors, err) + } else { + for _, n := range namespaces { + rules, errors := u.calculator.namespacedRuleResolver.RulesFor(u.user, n.Name) + + // Filter out NotFound error for any missing cluster role to match the k8s API + curatedError := utilerrors.FilterOut(errors, func(err error) bool { + return k8serrors.IsNotFound(err) + }) + if curatedError != nil { + u.errors = append(u.errors, curatedError) + } else if len(rules) > 0 { + u.namespacedRules[n.Name] = rules + } + } + } + log.Debugf("getNamespacedRules returns %v", u.namespacedRules) + } + return u.namespacedRules +} + +func (u *userCalculator) Calculate(rvs []ResourceVerbs) (Permissions, error) { + for _, rv := range rvs { + u.updatePermissions(rv.ResourceType, rv.Verbs) + } + return u.permissions, utilerrors.Flatten(utilerrors.NewAggregate(u.errors)) +} + +// updatePermissions calculates the RBAC permissions for a specific resource type and set of verbs, and updates the +// Permissions response struct. +func (u *userCalculator) updatePermissions(rt ResourceType, verbs []Verb) { + // Remove the sub-resource if present. + parts := strings.SplitN(rt.Resource, "/", 2) + mainresource := ResourceType{ + APIGroup: rt.APIGroup, + Resource: parts[0], + } + var subresource string + if len(parts) == 2 { + subresource = parts[1] + } + + // Look up the APIResource info for the primary resource (i.e. not the subresource). + ar, ok := u.resources[mainresource] + if !ok && !u.resourcesUpdated { + // This is an unknown resource type, we permit an update of the resources at most once per request. + log.Debugf("Resource type %s not found, update cached resource types", rt) + u.resourcesUpdated = true + u.updateResources() + ar, ok = u.resources[rt] + } + + u.permissions[rt] = make(map[Verb][]Match) + for _, verb := range verbs { + log.Debugf("Accumulating results for: %s %s", verb, rt) + if ok { + // The resource is registered so determine the matches from the RBAC config. + u.permissions[rt][verb] = u.getMatches(verb, ar, subresource) + } else { + // The resource is not registered so do not add any matches for this resource/verb combination. + u.permissions[rt][verb] = nil + } + } +} + +func (u *userCalculator) updateResources() { + // Grab the resource lock + u.calculator.resourceLock.Lock() + defer u.calculator.resourceLock.Unlock() + + if u.calculator.resourceUpdateTime == u.resourcesUpdateTime { + // The cache has not been updated since the query began, so update it now. If any errors occur the cache will + // not be updated and the data will remain out-of-date - this is fine, we'll simply not include the results. + err := u.calculator.loadResources() + if err != nil { + log.WithError(err).Warnf("Unable to update registered resource list - calculated RBAC may be incomplete") + return + } + } + + // Update the user-specific cache to point to the current cache. + log.Debug("Update user calculator to use updated cache of known resource types") + u.resources = u.calculator.resources + u.resourcesUpdateTime = u.calculator.resourceUpdateTime +} diff --git a/apiserver/pkg/rbac/calculator_test.go b/apiserver/pkg/rbac/calculator_test.go new file mode 100644 index 00000000000..0ba5af5628c --- /dev/null +++ b/apiserver/pkg/rbac/calculator_test.go @@ -0,0 +1,955 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +package rbac_test + +import ( + "encoding/json" + + . "github.com/projectcalico/calico/apiserver/pkg/rbac" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + gomegatypes "github.com/onsi/gomega/types" + + rbac_v1 "k8s.io/api/rbac/v1" + "k8s.io/apiserver/pkg/authentication/user" + + rbacmock "github.com/projectcalico/calico/apiserver/pkg/rbac/mock" +) + +var ( + resourceHostEndpoints = ResourceType{ + APIGroup: "projectcalico.org", + Resource: "hostendpoints", + } + resourceTiers = ResourceType{ + APIGroup: "projectcalico.org", + Resource: "tiers", + } + resourceCalicoNetworkPolicies = ResourceType{ + APIGroup: "projectcalico.org", + Resource: "networkpolicies", + } + resourceGlobalNetworkPolicies = ResourceType{ + APIGroup: "projectcalico.org", + Resource: "globalnetworkpolicies", + } + resourceNetworkSets = ResourceType{ + APIGroup: "projectcalico.org", + Resource: "networksets", + } + resourceGlobalNetworkSets = ResourceType{ + APIGroup: "projectcalico.org", + Resource: "globalnetworksets", + } + resourceKubernetesNetworkPolicies = ResourceType{ + APIGroup: "networking.k8s.io", + Resource: "networkpolicies", + } + resourceLegacyKubernetesNetworkPolicies = ResourceType{ + APIGroup: "extensions", + Resource: "networkpolicies", + } + resourceNamespaces = ResourceType{ + APIGroup: "", + Resource: "namespaces", + } + resourcePods = ResourceType{ + APIGroup: "", + Resource: "pods", + } + + tieredPolicyResources = []ResourceType{ + resourceCalicoNetworkPolicies, + resourceGlobalNetworkPolicies, + } + + namespacedResources = []ResourceType{ + resourceNetworkSets, + resourceLegacyKubernetesNetworkPolicies, + resourceKubernetesNetworkPolicies, + resourcePods, + resourceCalicoNetworkPolicies, + } + + clusterScopedResources = []ResourceType{ + resourceHostEndpoints, + resourceTiers, + resourceNamespaces, + resourceGlobalNetworkSets, + resourceGlobalNetworkPolicies, + } + + defaultResourceTypes = []ResourceType{ + resourceHostEndpoints, + resourceTiers, + resourceNamespaces, + resourceNetworkSets, + resourceGlobalNetworkSets, + resourceLegacyKubernetesNetworkPolicies, + resourceKubernetesNetworkPolicies, + resourcePods, + resourceCalicoNetworkPolicies, + resourceGlobalNetworkPolicies, + } +) + +func isOneOf(rt ResourceType, rts ...ResourceType) bool { + for _, rtss := range rts { + if rt == rtss { + return true + } + } + return false +} + +var allResourceVerbs []ResourceVerbs + +func init() { + for _, rt := range defaultResourceTypes { + allResourceVerbs = append(allResourceVerbs, ResourceVerbs{ + rt, AllVerbs, + }) + } +} + +var _ = Describe("RBAC calculator tests", func() { + var calc Calculator + var mock *rbacmock.MockClient + var myUser user.Info + + BeforeEach(func() { + mock = &rbacmock.MockClient{ + Roles: map[string][]rbac_v1.PolicyRule{}, + RoleBindings: map[string][]string{}, + ClusterRoles: map[string][]rbac_v1.PolicyRule{}, + ClusterRoleBindings: []string{}, + Namespaces: []string{"ns1", "ns2", "ns3", "ns4", "ns5"}, + Tiers: []string{"default", "tier1", "tier2", "tier3", "tier4"}, + } + calc = NewCalculator(mock, mock, mock, mock, mock, mock, mock, 0) + myUser = &user.DefaultInfo{ + Name: "my-user", + UID: "abcde", + Groups: []string{}, + Extra: map[string][]string{}, + } + }) + + It("handles errors in the Namespace enumeration", func() { + mock.Namespaces = nil + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no Namespaces set")) + expectPresentButEmpty(res, allResourceVerbs) + }) + + It("handles errors in the ClusterRoleBinding enumeration", func() { + mock.ClusterRoleBindings = nil + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no ClusterRoleBindings set")) + expectPresentButEmpty(res, allResourceVerbs) + }) + + It("handles errors in the ClusterRole enumeration from ClusterRoleBinding", func() { + mock.ClusterRoleBindings = []string{"test"} + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).NotTo(HaveOccurred()) + expectPresentButEmpty(res, allResourceVerbs) + }) + + It("handles errors in the RoleBinding enumeration", func() { + mock.RoleBindings = nil + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no RoleBindings set")) + expectPresentButEmpty(res, allResourceVerbs) + }) + + It("handles errors in the ClusterRole enumeration from RoleBinding", func() { + mock.RoleBindings = map[string][]string{"ns1": {"test"}} + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).NotTo(HaveOccurred()) + expectPresentButEmpty(res, allResourceVerbs) + }) + + It("handles errors in the Role enumeration from RoleBinding", func() { + mock.RoleBindings = map[string][]string{"ns1": {"/test"}} + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Role(ns1/test) does not exist")) + expectPresentButEmpty(res, allResourceVerbs) + }) + + It("matches cluster scoped wildcard name matches for all resources", func() { + mock.ClusterRoleBindings = []string{"all-resources"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "all-resources": {{ + Verbs: []string{"update", "create", "list", "get"}, + Resources: []string{"*"}, + APIGroups: []string{"*"}, + }}, + } + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveLen(len(defaultResourceTypes)), "one result for each resource type") + + Describe("all resources", func() { + for _, resourceType := range defaultResourceTypes { + Expect(res).To(HaveKey(resourceType), "one result for each resource type") + Expect(res[resourceNamespaces]).To(haveMatchAllForVerbs( + VerbUpdate, + VerbCreate, + VerbList, + )) + Expect(res[resourceNamespaces]).To(haveMatchNoneForVerbs( + VerbPatch, + VerbDelete, + VerbWatch, + )) + + // assert get is non-nil. it's value will be different for certain resources as tested independently below + Expect(res[resourceNamespaces][VerbGet]).ToNot(BeNil()) + } + }) + + Describe("tiered policies", func() { + for _, resourceType := range tieredPolicyResources { + Expect(res[resourceType]).To(haveOnlyMatchesForVerbs([]Match{ + {Tier: "default"}, + {Tier: "tier1"}, + {Tier: "tier2"}, + {Tier: "tier3"}, + {Tier: "tier4"}, + }, VerbUpdate, VerbCreate, VerbList, VerbGet), resourceType.String()) + } + }) + + Describe("namespaces", func() { + Expect(res[resourceNamespaces]).To(haveMatchForVerbs([]Match{ + {Namespace: "ns1"}, + {Namespace: "ns2"}, + {Namespace: "ns3"}, + {Namespace: "ns4"}, + {Namespace: "ns5"}, + }, VerbGet)) + }) + + Describe("get tiers", func() { + Expect(res[resourceTiers]).To(haveMatchForVerbs([]Match{ + {Tier: "default"}, + {Tier: "tier1"}, + {Tier: "tier2"}, + {Tier: "tier3"}, + {Tier: "tier4"}, + }, VerbGet)) + }) + }) + + It("matches cluster scoped wildcard tier matches for all resources with get access to limited Tiers", func() { + gettableTiers := []string{"default", "tier2"} + mock.ClusterRoleBindings = []string{"all-resources", "get-tiers"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "all-resources": {{ + APIGroups: []string{"*"}, + Resources: []string{"*"}, + Verbs: []string{"delete", "patch"}, + }}, + "get-tiers": {{ + APIGroups: []string{"projectcalico.org"}, + Resources: []string{"tiers"}, + Verbs: []string{"get"}, + ResourceNames: gettableTiers, + }}, + } + + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveLen(len(defaultResourceTypes))) + Describe("all resources", func() { + for _, resourceType := range defaultResourceTypes { + Expect(res).To(HaveKey(resourceType), "one result for each resource type") + Expect(res[resourceType]).To(HaveLen(len(AllVerbs)), "one result for each defined verb") + if isOneOf(resourceType, resourceTiers) || isOneOf(resourceType, tieredPolicyResources...) { + // test separately below as they additionally have 'get' permission. + continue + } + Expect(res[resourceType]).To(haveOnlyMatchesForVerbs([]Match{{}}, VerbPatch, VerbDelete), resourceType.String()) + } + }) + + Describe("tiers", func() { + Expect(res[resourceTiers]).To(haveMatchNoneForVerbs(VerbWatch, VerbCreate, VerbList, VerbUpdate)) + Expect(res[resourceTiers]).To(haveMatchAllForVerbs(VerbDelete, VerbPatch)) + Expect(res[resourceTiers]).To(haveMatchForVerbs([]Match{ + {Tier: "default"}, + {Tier: "tier2"}, + }, VerbGet)) + }) + + Describe("tiered policies", func() { + // Matches for tiered policy should only contain the gettable Tiers. + for _, resourceType := range tieredPolicyResources { + Expect(res[resourceType]).To(haveOnlyMatchesForVerbs([]Match{ + {Tier: "default"}, + {Tier: "tier2"}, + }, VerbDelete, VerbPatch), resourceType.String()) + } + }) + + Describe("all other resources", func() { + for _, resourceType := range []ResourceType{ + resourceHostEndpoints, + resourceNamespaces, + resourceNetworkSets, + resourceGlobalNetworkSets, + resourceLegacyKubernetesNetworkPolicies, + resourcePods, + resourceKubernetesNetworkPolicies, + } { + Expect(res[resourceType]).To(haveMatchAllForVerbs(VerbDelete, VerbPatch), resourceType.String()) + Expect(res[resourceType]).To(haveMatchNoneForVerbs(VerbGet, VerbList, VerbUpdate, VerbCreate, VerbWatch)) + } + }) + }) + + It("matches wildcard name matches for all resources in namespace ns1, get access all Tiers and UISettingsGroups", func() { + mock.ClusterRoleBindings = []string{"get-tiers", "get-uisettingsgroups"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-tiers": {{ + Verbs: []string{"get"}, + Resources: []string{"tiers"}, + APIGroups: []string{"projectcalico.org"}, + }}, + "get-uisettingsgroups": {{ + Verbs: []string{"get"}, + Resources: []string{"uisettingsgroups"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + mock.RoleBindings = map[string][]string{"ns1": {"/all-resources"}} + mock.Roles = map[string][]rbac_v1.PolicyRule{ + "ns1/all-resources": {{ + Verbs: []string{"update", "create", "list"}, + Resources: []string{"*"}, + APIGroups: []string{"*"}, + }}, + } + // We should only get results for namespaced resources + get for Tiers + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveLen(len(defaultResourceTypes))) + + Describe("cluster-scoped resources", func() { + for _, resourceType := range clusterScopedResources { + Expect(res).To(HaveKey(resourceType), "one result for each resource type") + Expect(res[resourceType]).To(HaveLen(len(AllVerbs)), "one result for each defined verb") + if resourceType == resourceNamespaces || + resourceType == resourceTiers { + // test separately below as they additionally have 'get' permission. + continue + } + Expect(res[resourceType]).To(haveMatchNoneForAllVerbs(), resourceType.String()) + } + }) + + Describe("namespaces", func() { + Expect(res[resourceNamespaces]).To(haveMatchNoneForAllVerbs()) + }) + + Describe("tiers", func() { + Expect(res[resourceTiers]).To(haveOnlyMatchesForVerbs([]Match{ + {Tier: "default"}, + {Tier: "tier1"}, + {Tier: "tier2"}, + {Tier: "tier3"}, + {Tier: "tier4"}, + }, VerbGet)) + }) + + Describe("cluster-scoped tiered policy resources", func() { + for _, resourceType := range []ResourceType{ + resourceGlobalNetworkPolicies, + } { + Expect(res[resourceType]).To(haveMatchNoneForAllVerbs(), resourceType.String()) + } + }) + + Describe("namespaced tiered policy resources", func() { + for _, resourceType := range []ResourceType{ + resourceCalicoNetworkPolicies, + } { + Expect(res[resourceType]).To(haveMatchForVerbs([]Match{ + {Namespace: "ns1", Tier: "default"}, + {Namespace: "ns1", Tier: "tier1"}, + {Namespace: "ns1", Tier: "tier2"}, + {Namespace: "ns1", Tier: "tier3"}, + {Namespace: "ns1", Tier: "tier4"}, + }, VerbUpdate, VerbCreate, VerbList), resourceType.String()) + Expect(res[resourceType]).To(haveMatchNoneForVerbs(VerbGet, VerbDelete, VerbPatch, VerbWatch), resourceType.String()) + } + }) + + Describe("namespaced", func() { + for _, resourceType := range namespacedResources { + Expect(res[resourceType]).To(HaveLen(len(AllVerbs))) + if resourceType == resourceCalicoNetworkPolicies { + Describe("tiered policy resources", func() { + Expect(res[resourceType]).To(haveMatchForVerbs([]Match{ + {Namespace: "ns1", Tier: "default"}, + {Namespace: "ns1", Tier: "tier1"}, + {Namespace: "ns1", Tier: "tier2"}, + {Namespace: "ns1", Tier: "tier3"}, + {Namespace: "ns1", Tier: "tier4"}, + }, VerbUpdate, VerbCreate, VerbList), resourceType.String()) + Expect(res[resourceType]).To(haveMatchNoneForVerbs(VerbGet, VerbDelete, VerbPatch, VerbWatch), resourceType.String()) + }) + } else { + Describe("resources (excluding tiered-policy resources", func() { + Expect(res[resourceType]).To(haveMatchForVerbs([]Match{{Namespace: "ns1"}}, VerbUpdate, VerbCreate, VerbList), resourceType.String()) + Expect(res[resourceType]).To(haveMatchNoneForVerbs(VerbGet, VerbDelete, VerbPatch, VerbWatch), resourceType.String()) + }) + } + } + }) + }) + + It("matches namespace scoped wildcard name matches for all resources, no get access to any tier", func() { + mock.RoleBindings = map[string][]string{"ns1": {"/all-resources"}} + mock.Roles = map[string][]rbac_v1.PolicyRule{ + "ns1/all-resources": {{ + Verbs: []string{"update", "create", "list"}, + Resources: []string{"*"}, + APIGroups: []string{"*"}, + }}, + } + // We should only get results for namespaced non-tiered policies + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveLen(len(defaultResourceTypes))) + + // namespaced resources that aren't tiered policies should have ns matchers + Describe("namespaced", func() { + for _, resourceType := range namespacedResources { + Expect(res[resourceType]).To(HaveLen(len(AllVerbs)), "one result for each defined verb") + if resourceType == resourceCalicoNetworkPolicies { + Describe("tiered policy resources", func() { + Expect(res[resourceType]).To(haveMatchNoneForAllVerbs(), resourceType.String()) + }) + } else { + Describe("resources (except tiered-policies)", func() { + Expect(res[resourceType]).To(haveMatchForVerbs([]Match{{Namespace: "ns1"}}, VerbUpdate, VerbCreate, VerbList)) + Expect(res[resourceType]).To(haveMatchNoneForVerbs(VerbGet, VerbDelete, VerbPatch, VerbWatch)) + }) + } + } + }) + + Describe("cluster-scoped", func() { + for _, resourceType := range clusterScopedResources { + Expect(res[resourceType]).To(HaveLen(len(AllVerbs)), "one result for each defined verb") + Expect(res[resourceType]).To(haveMatchNoneForAllVerbs()) + } + }) + }) + + It("matches namespace scoped wildcard name matches for all resources with get access to limited Tiers", func() { + gettableTiers := []string{"tier2", "tier3"} + mock.ClusterRoleBindings = []string{"get-tiers"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-tiers": {{ + Verbs: []string{"get"}, + Resources: []string{"tiers"}, + ResourceNames: gettableTiers, + APIGroups: []string{"*"}, + }}, + } + mock.RoleBindings = map[string][]string{"ns1": {"/test"}} + mock.Roles = map[string][]rbac_v1.PolicyRule{ + "ns1/test": {{ + Verbs: []string{"delete", "patch", "list", "watch"}, + Resources: []string{"*"}, + APIGroups: []string{"*"}, + }}, + } + + // Since we do not have get access to all Tiers, the wildcard tier match will be expanded. Also the tier + // resource will be expanded too. So we'd expect: + // - Get for each tier (2) + // - Delete/Patch/Watch/List for each namespaced tiered policy type in each tier (4 * 2) + // - Delete/Patch/Watch/List for other namespaced resource types + res, err := calc.CalculatePermissions(myUser, allResourceVerbs) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveLen(len(defaultResourceTypes))) + + Describe("tiers", func() { + Expect(res[resourceTiers]).To(Equal(map[Verb][]Match{ + VerbGet: { + {Tier: "tier2"}, + {Tier: "tier3"}, + }, + VerbUpdate: nil, + VerbCreate: nil, + VerbList: nil, + VerbDelete: nil, + VerbPatch: nil, + VerbWatch: nil, + })) + }) + + // namespaced resources that aren't tiered policies should have ns matchers + Describe("namespaced", func() { + for _, resourceType := range namespacedResources { + Expect(res[resourceType]).To(HaveLen(len(AllVerbs)), "one result for each defined verb") + if resourceType == resourceCalicoNetworkPolicies { + Describe("tiered policy resources", func() { + Expect(res[resourceType]).To(Equal(map[Verb][]Match{ + VerbCreate: nil, + VerbPatch: {{Tier: "tier2", Namespace: "ns1"}, {Tier: "tier3", Namespace: "ns1"}}, + VerbDelete: {{Tier: "tier2", Namespace: "ns1"}, {Tier: "tier3", Namespace: "ns1"}}, + VerbWatch: {{Tier: "tier2", Namespace: "ns1"}, {Tier: "tier3", Namespace: "ns1"}}, + VerbGet: nil, + VerbUpdate: nil, + VerbList: {{Tier: "tier2", Namespace: "ns1"}, {Tier: "tier3", Namespace: "ns1"}}, + }), resourceType.String()) + }) + } else { + Describe("resources (except tiered-policies)", func() { + Expect(res[resourceType]).To(Equal(map[Verb][]Match{ + VerbCreate: nil, + VerbPatch: {{Namespace: "ns1"}}, + VerbDelete: {{Namespace: "ns1"}}, + VerbWatch: {{Namespace: "ns1"}}, + VerbGet: nil, + VerbUpdate: nil, + VerbList: {{Namespace: "ns1"}}, + }), resourceType.String()) + }) + } + } + }) + + Describe("cluster-scoped", func() { + for _, resourceType := range clusterScopedResources { + if resourceType == resourceTiers { + // handle tiers separately as they have different GET permissions + continue + } + Expect(res[resourceType]).To(haveMatchNoneForAllVerbs(), resourceType.String()) + } + }) + }) + + It("matches namespace scoped wildcard name for CNP + cluster scoped tier-specific CNP + namespace scoped tier-specific CNP, with get access on all Tiers", func() { + mock.ClusterRoleBindings = []string{"get-tiers", "wildcard-create", "tier1-patch"} + mock.RoleBindings = map[string][]string{ + "ns2": {"wildcard-delete", "tier2-create", "tier1-patch", "tier2-delete"}, + "ns3": {"tier2-delete", "tier1-listwatch"}, + } + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-tiers": {{Verbs: []string{"get"}, Resources: []string{"tiers"}, APIGroups: []string{"projectcalico.org"}}}, + "tier1-patch": {{ + Verbs: []string{"patch"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + ResourceNames: []string{"tier1.*"}, + }}, + "tier1-listwatch": {{ + Verbs: []string{"watch", "list"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + ResourceNames: []string{"tier1.*"}, + }}, + "tier2-create": {{ + Verbs: []string{"create"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + ResourceNames: []string{"tier2.*"}, + }}, + "tier2-delete": {{ + Verbs: []string{"delete"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + ResourceNames: []string{"tier2.*"}, + }}, + "wildcard-delete": {{ + Verbs: []string{"delete"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + }}, + "wildcard-create": {{ + Verbs: []string{"create"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + + // Request permissions for calico network policies only. + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceCalicoNetworkPolicies, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveLen(1)) + Expect(res).To(HaveKey(resourceCalicoNetworkPolicies)) + m := res[resourceCalicoNetworkPolicies] + Expect(m["get"]).To(BeNil()) + Expect(m["update"]).To(BeNil()) + Expect(m["list"]).To(Equal([]Match{{Namespace: "ns3", Tier: "tier1"}})) + Expect(m["watch"]).To(Equal([]Match{{Namespace: "ns3", Tier: "tier1"}})) + Expect(m["create"]).To(ConsistOf([]Match{ + {Namespace: "", Tier: "default"}, + {Namespace: "", Tier: "tier1"}, + {Namespace: "", Tier: "tier2"}, + {Namespace: "", Tier: "tier3"}, + {Namespace: "", Tier: "tier4"}, + })) + Expect(m["delete"]).To(ConsistOf([]Match{ + {Namespace: "ns2", Tier: "default"}, + {Namespace: "ns2", Tier: "tier1"}, + {Namespace: "ns2", Tier: "tier2"}, + {Namespace: "ns2", Tier: "tier3"}, + {Namespace: "ns2", Tier: "tier4"}, + {Namespace: "ns3", Tier: "tier2"}, + })) + Expect(m["patch"]).To(Equal([]Match{{Namespace: "", Tier: "tier1"}})) + }) + + It("has fully gettable and watchable Tiers, but not listable", func() { + mock.ClusterRoleBindings = []string{"get-watch-Tiers"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-watch-Tiers": {{ + Verbs: []string{"get", "watch"}, + Resources: []string{"tiers"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + + // We should have watch access at cluster scope + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceTiers, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(resourceTiers)) + nps := res[resourceTiers] + Expect(nps).To(HaveKey(VerbList)) + Expect(nps).To(HaveKey(VerbWatch)) + Expect(nps[VerbList]).To(BeNil()) + Expect(nps[VerbWatch]).To(Equal([]Match{{}})) + }) + + It("has fully gettable Tiers, but no list and limited watch access to Tiers", func() { + mock.ClusterRoleBindings = []string{"get-tiers", "watch-list-tiers1-2"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-tiers": {{ + Verbs: []string{"get"}, + Resources: []string{"tiers"}, + APIGroups: []string{"projectcalico.org"}, + }}, + "watch-list-tiers1-2": {{ + Verbs: []string{"watch"}, + Resources: []string{"tiers"}, + ResourceNames: []string{"tier1", "tier2"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + + // We should have watch access for specific gettable Tiers. + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceTiers, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(resourceTiers)) + nps := res[resourceTiers] + Expect(nps).To(HaveKey(VerbList)) + Expect(nps).To(HaveKey(VerbWatch)) + Expect(nps[VerbList]).To(BeNil()) + Expect(nps[VerbWatch]).To(Equal([]Match{{Tier: "tier1"}, {Tier: "tier2"}})) + }) + + It("has fully gettable and createable namespaces limited watch access to Namespaces", func() { + mock.ClusterRoleBindings = []string{"get-create-namespaces", "watch-ns1-2"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-create-namespaces": {{ + Verbs: []string{"get", "create"}, + Resources: []string{"namespaces"}, + APIGroups: []string{""}, + }}, + "watch-ns1-2": {{ + Verbs: []string{"watch"}, + Resources: []string{"namespaces"}, + ResourceNames: []string{"ns1", "ns2"}, + APIGroups: []string{""}, + }}, + } + + // Namespace gets should be expanded and so whould wathc it cluster-wide watch is not authorized. + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceNamespaces, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(resourceNamespaces)) + nps := res[resourceNamespaces] + Expect(nps).To(HaveKey(VerbGet)) + Expect(nps).To(HaveKey(VerbCreate)) + Expect(nps).To(HaveKey(VerbWatch)) + Expect(nps[VerbWatch]).To(Equal([]Match{{Namespace: "ns1"}, {Namespace: "ns2"}})) + Expect(nps[VerbGet]).To(Equal([]Match{{Namespace: "ns1"}, {Namespace: "ns2"}, {Namespace: "ns3"}, {Namespace: "ns4"}, {Namespace: "ns5"}})) + Expect(nps[VerbCreate]).To(Equal([]Match{{}})) + }) + + It("has watchable networkpolicies in all Tiers and listable in tier1 and tier2", func() { + mock.ClusterRoleBindings = []string{"get-watch-np"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-watch-np": {{ + Verbs: []string{"get"}, + Resources: []string{"tiers"}, + APIGroups: []string{"projectcalico.org"}, + }, { + Verbs: []string{"watch"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + }, { + Verbs: []string{"list"}, + Resources: []string{"tier.networkpolicies"}, + ResourceNames: []string{"tier1.*", "tier2.*"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + + // We should have watch access for each tier. + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceCalicoNetworkPolicies, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(resourceCalicoNetworkPolicies)) + nps := res[resourceCalicoNetworkPolicies] + Expect(nps).To(HaveKey(VerbList)) + Expect(nps).To(HaveKey(VerbWatch)) + Expect(nps[VerbList]).To(Equal([]Match{{Tier: "tier1"}, {Tier: "tier2"}})) + Expect(nps[VerbWatch]).To(Equal([]Match{{Tier: "default"}, {Tier: "tier1"}, {Tier: "tier2"}, {Tier: "tier3"}, {Tier: "tier4"}})) + }) + + It("has listable networkpolicies in all Tiers and watchable in tier1 and tier2", func() { + mock.ClusterRoleBindings = []string{"get-watch-np"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-watch-np": {{ + Verbs: []string{"get"}, + Resources: []string{"tiers"}, + APIGroups: []string{"projectcalico.org"}, + }, { + Verbs: []string{"list"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + }, { + Verbs: []string{"watch"}, + Resources: []string{"tier.networkpolicies"}, + ResourceNames: []string{"tier1.*", "tier2.*"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + + // List access for each tier, watch access limited to two Tiers. + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceCalicoNetworkPolicies, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(resourceCalicoNetworkPolicies)) + nps := res[resourceCalicoNetworkPolicies] + Expect(nps).To(HaveKey(VerbList)) + Expect(nps).To(HaveKey(VerbWatch)) + Expect(nps[VerbList]).To(Equal([]Match{{Tier: "default"}, {Tier: "tier1"}, {Tier: "tier2"}, {Tier: "tier3"}, {Tier: "tier4"}})) + Expect(nps[VerbWatch]).To(Equal([]Match{{Tier: "tier1"}, {Tier: "tier2"}})) + }) + + It("has listable pods/status and gettable pods", func() { + mock.ClusterRoleBindings = []string{"list-podsstatus", "get-pods"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "list-podsstatus": {{ + Verbs: []string{"list"}, + Resources: []string{"pods/status"}, + APIGroups: []string{""}, + }}, + "get-pods": {{ + Verbs: []string{"get"}, + Resources: []string{"pods"}, + APIGroups: []string{""}, + }}, + } + + // Check list/get access for pods and pods/status. + rpods := resourcePods + rpodstatus := ResourceType{APIGroup: "", Resource: "pods/status"} + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{rpods, AllVerbs}, {rpodstatus, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(rpods)) + Expect(res).To(HaveKey(rpodstatus)) + + pods := res[rpods] + Expect(pods).To(HaveKey(VerbGet)) + Expect(pods).To(HaveKey(VerbList)) + Expect(pods[VerbGet]).To(Equal([]Match{{}})) + Expect(pods[VerbList]).To(BeNil()) + + podstatus := res[rpodstatus] + Expect(podstatus).To(HaveKey(VerbGet)) + Expect(podstatus).To(HaveKey(VerbList)) + Expect(podstatus[VerbGet]).To(BeNil()) + Expect(podstatus[VerbList]).To(Equal([]Match{{}})) + }) + + It("has listable/watchable networkpolicies in all Tiers, gettable only in tier2 and tier3", func() { + mock.ClusterRoleBindings = []string{"get-watch-np"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-watch-np": {{ + Verbs: []string{"get"}, + Resources: []string{"tiers"}, + APIGroups: []string{"projectcalico.org"}, + ResourceNames: []string{"tier2", "tier3"}, + }, { + Verbs: []string{"list"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + }, { + Verbs: []string{"watch"}, + Resources: []string{"tier.networkpolicies"}, + APIGroups: []string{"projectcalico.org"}, + }}, + } + + // List/Watch access limited to gettable Tiers. + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{resourceCalicoNetworkPolicies, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(resourceCalicoNetworkPolicies)) + nps := res[resourceCalicoNetworkPolicies] + Expect(nps).To(HaveKey(VerbList)) + Expect(nps).To(HaveKey(VerbWatch)) + Expect(nps[VerbList]).To(Equal([]Match{{Tier: "tier2"}, {Tier: "tier3"}})) + Expect(nps[VerbWatch]).To(Equal([]Match{{Tier: "tier2"}, {Tier: "tier3"}})) + }) + + It("requeries the cache for an unknown resource type", func() { + mock.ClusterRoleBindings = []string{"get-fake"} + mock.ClusterRoles = map[string][]rbac_v1.PolicyRule{ + "get-fake": {{ + Verbs: []string{"get"}, + Resources: []string{"dummy0", "dummy1", "dummy2"}, + APIGroups: []string{"fake"}, + }}, + } + + // Query resource "dummy0". This should be cached first iteration of the mock client. + rt := ResourceType{APIGroup: "fake", Resource: "dummy0"} + res, err := calc.CalculatePermissions(myUser, []ResourceVerbs{{rt, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(rt)) + nps := res[rt] + Expect(nps[VerbGet]).To(Equal([]Match{{}})) + + // Query resource "dummy2". This is not in the cache. A second query will update dummy0 to dummy1, but dummy2 + // will still not be in the cache so will not be permitted. + rt = ResourceType{APIGroup: "fake", Resource: "dummy2"} + res, err = calc.CalculatePermissions(myUser, []ResourceVerbs{{rt, AllVerbs}}) + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(HaveKey(rt)) + nps = res[rt] + Expect(nps[VerbGet]).To(BeNil()) + + // Query resource "dummy2" again. This is not in the cache, but a second query will update dummy1 to dummy2. + rt = ResourceType{APIGroup: "fake", Resource: "dummy2"} + res, err = calc.CalculatePermissions(myUser, []ResourceVerbs{{rt, AllVerbs}}) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(HaveKey(rt)) + nps = res[rt] + Expect(nps[VerbGet]).To(Equal([]Match{{}})) + + // Query resource "dummy0". This is not in the cache anymore because the mock client has clocked past it. + rt = ResourceType{APIGroup: "fake", Resource: "dummy0"} + res, err = calc.CalculatePermissions(myUser, []ResourceVerbs{{rt, AllVerbs}}) + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(HaveKey(rt)) + nps = res[rt] + Expect(nps[VerbGet]).To(BeNil()) + }) + + It("can marshal and unmarshal a Permissions into json", func() { + By("marshaling a Permissions struct") + p := Permissions{ + resourceCalicoNetworkPolicies: map[Verb][]Match{ + VerbGet: {{Tier: "a", Namespace: "b"}}, + }, + resourcePods: map[Verb][]Match{ + VerbList: {{Namespace: "b"}}, + }, + } + + v, err := json.Marshal(p) + Expect(err).NotTo(HaveOccurred()) + + expected := `{ + "networkpolicies.projectcalico.org": {"get": [{"tier": "a", "namespace": "b"}]}, + "pods": {"list": [{"tier": "", "namespace": "b"}]} +}` + Expect(v).To(MatchJSON(expected)) + + By("Unmarshaling the json and comparing to the original") + p2 := Permissions{} + err = json.Unmarshal(v, &p2) + Expect(err).NotTo(HaveOccurred()) + Expect(p2).To(Equal(p)) + }) +}) + +func haveMatchAllForVerbs(expectedVerbs ...Verb) gomegatypes.GomegaMatcher { + return haveMatchForVerbs([]Match{{}}, expectedVerbs...) +} + +func haveMatchNoneForVerbs(expectedVerbs ...Verb) gomegatypes.GomegaMatcher { + return haveMatchForVerbs(nil, expectedVerbs...) +} + +func haveMatchNoneForAllVerbs() gomegatypes.GomegaMatcher { + return haveOnlyMatchesForVerbs(nil, AllVerbs...) +} + +// haveMatchForVerbs asserts that the passed verbs all have matches equal to the passed matches. +// it does nothing to assert on the remaining verbs. this should be done separately, probably with a subsequent call +// to this function. +func haveMatchForVerbs(matches []Match, verbs ...Verb) gomegatypes.GomegaMatcher { + matchers := []gomegatypes.GomegaMatcher{} + for _, verb := range verbs { + matchers = append(matchers, HaveKey(verb)) + matchers = append(matchers, HaveKeyWithValue(verb, matches)) + } + + return SatisfyAll(matchers...) +} + +// haveOnlyMatchesForVerbs tests that the passed verbs all have matches equal to the passed matches, +// and that all other known verbs are nil. +func haveOnlyMatchesForVerbs(matches []Match, verbs ...Verb) gomegatypes.GomegaMatcher { + matchers := []gomegatypes.GomegaMatcher{ + HaveLen(len(AllVerbs)), + } + for _, verb := range AllVerbs { + // all verbs should be present even if not expected + matchers = append(matchers, HaveKey(verb)) + if contains(verbs, verb) { + matchers = append(matchers, HaveKeyWithValue(verb, matches)) + } else { + matchers = append(matchers, HaveKeyWithValue(verb, BeNil())) + } + } + + return SatisfyAll(matchers...) +} + +func expectPresentButEmpty(p Permissions, rvs []ResourceVerbs) { + Expect(p).To(HaveLen(len(rvs))) + for _, rv := range rvs { + vs, ok := p[rv.ResourceType] + Expect(ok).To(BeTrue()) + Expect(vs).To(HaveLen(len(rv.Verbs))) + for _, v := range rv.Verbs { + m, ok := vs[v] + Expect(ok).To(BeTrue()) + Expect(m).To(BeNil()) + } + } +} + +func contains[T comparable](elems []T, v T) bool { + for _, s := range elems { + if v == s { + return true + } + } + return false +} diff --git a/apiserver/pkg/rbac/mock/client.go b/apiserver/pkg/rbac/mock/client.go new file mode 100644 index 00000000000..4c810c19856 --- /dev/null +++ b/apiserver/pkg/rbac/mock/client.go @@ -0,0 +1,205 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package mock + +import ( + "fmt" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" + + log "github.com/sirupsen/logrus" + + core_v1 "k8s.io/api/core/v1" + rbac_v1 "k8s.io/api/rbac/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" +) + +type MockClient struct { + Roles map[string][]rbac_v1.PolicyRule + RoleBindings map[string][]string + ClusterRoles map[string][]rbac_v1.PolicyRule + ClusterRoleBindings []string + Namespaces []string + Tiers []string + ResourcesQueries int +} + +func (m *MockClient) ServerPreferredResources() ([]*meta_v1.APIResourceList, error) { + rl := []*meta_v1.APIResourceList{ + { + GroupVersion: "v1", + APIResources: []meta_v1.APIResource{ + {Name: "pods", Namespaced: true}, + {Name: "namespaces", Namespaced: false}, + }, + }, + { + GroupVersion: "extensions/v1beta1", + APIResources: []meta_v1.APIResource{ + {Name: "networkpolicies", Namespaced: true}, + }, + }, + { + GroupVersion: "networking.k8s.io/v1", + APIResources: []meta_v1.APIResource{ + {Name: "networkpolicies", Namespaced: true}, + }, + }, + { + GroupVersion: "projectcalico.org/v3", + APIResources: []meta_v1.APIResource{ + {Name: "hostendpoints", Namespaced: false}, + {Name: "tiers", Namespaced: false}, + {Name: "networkpolicies", Namespaced: true}, + {Name: "globalnetworkpolicies", Namespaced: false}, + {Name: "networksets", Namespaced: true}, + {Name: "globalnetworksets", Namespaced: false}, + }, + }, + + // Add a fake resource with a resource name that clocks with the number of times this is invoked. This is used + // to test recaching of the data. + { + GroupVersion: "fake/v3", + APIResources: []meta_v1.APIResource{ + {Name: fmt.Sprintf("dummy%d", m.ResourcesQueries), Namespaced: true}, + }, + }, + } + + log.Debugf("Included resource dummy%d.fake", m.ResourcesQueries) + m.ResourcesQueries++ + + return rl, nil +} + +func (m *MockClient) GetRole(namespace, name string) (*rbac_v1.Role, error) { + rules := m.Roles[namespace+"/"+name] + if rules == nil { + log.Debug("GetRole returning error") + return nil, fmt.Errorf("Role(%s/%s) does not exist", namespace, name) + } + + log.Debug("GetRole returning no error") + return &rbac_v1.Role{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Rules: rules, + }, nil +} + +func (m *MockClient) ListRoleBindings(namespace string) ([]*rbac_v1.RoleBinding, error) { + if m.RoleBindings == nil { + log.Debug("ListRoleBindings returning error") + return nil, fmt.Errorf("no RoleBindings set") + } + + names := m.RoleBindings[namespace] + + log.Debugf("ListRoleBindings returning %d results", len(names)) + bindings := make([]*rbac_v1.RoleBinding, len(names)) + for i, name := range names { + kind := "ClusterRole" + if name[0] == '/' { + name = name[1:] + kind = "Role" + } + bindings[i] = &rbac_v1.RoleBinding{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: fmt.Sprintf("role-binding-%d", i), + Namespace: namespace, + }, + Subjects: []rbac_v1.Subject{{ + Kind: "User", + Name: "my-user", + }}, + RoleRef: rbac_v1.RoleRef{ + Kind: kind, + Name: name, + }, + } + } + return bindings, nil +} + +func (m *MockClient) GetClusterRole(name string) (*rbac_v1.ClusterRole, error) { + rules := m.ClusterRoles[name] + if rules == nil { + log.Debug("GetClusterRole returning error") + return nil, k8serrors.NewNotFound(schema.ParseGroupResource("clusterrole.rbac.authorization.k8s.io"), name) + } + + log.Debug("GetClusterRole returning no error") + return &rbac_v1.ClusterRole{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: name, + }, + Rules: rules, + }, nil +} + +func (m *MockClient) ListClusterRoleBindings() ([]*rbac_v1.ClusterRoleBinding, error) { + if m.ClusterRoleBindings == nil { + return nil, fmt.Errorf("no ClusterRoleBindings set") + } + + names := m.ClusterRoleBindings + log.Debugf("ListClusterRoleBindings returning %d results", len(names)) + + bindings := make([]*rbac_v1.ClusterRoleBinding, len(names)) + for i, name := range names { + bindings[i] = &rbac_v1.ClusterRoleBinding{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: fmt.Sprintf("clusterrole-binding-%d", i), + }, + Subjects: []rbac_v1.Subject{{ + Kind: "User", + Name: "my-user", + }}, + RoleRef: rbac_v1.RoleRef{ + Kind: "ClusterRole", + Name: name, + }, + } + } + return bindings, nil +} + +func (m *MockClient) ListNamespaces() ([]*core_v1.Namespace, error) { + if m.Namespaces == nil { + log.Debug("ListNamespaces returning error") + return nil, fmt.Errorf("no Namespaces set") + } + log.Debugf("ListNamespaces returning %d results", len(m.Namespaces)) + namespaces := make([]*core_v1.Namespace, len(m.Namespaces)) + for i, name := range m.Namespaces { + namespaces[i] = &core_v1.Namespace{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: name, + }, + } + } + return namespaces, nil +} + +func (m *MockClient) ListTiers() ([]*v3.Tier, error) { + if m.Tiers == nil { + log.Debug("ListTiers returning error") + return nil, fmt.Errorf("no Tiers set") + } + log.Debugf("ListTiers returning %d results", len(m.Tiers)) + tiers := make([]*v3.Tier, len(m.Tiers)) + for i, name := range m.Tiers { + tiers[i] = &v3.Tier{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: name, + }, + } + } + return tiers, nil +} diff --git a/apiserver/pkg/rbac/rbac_suite_test.go b/apiserver/pkg/rbac/rbac_suite_test.go new file mode 100644 index 00000000000..ca1739b1fa5 --- /dev/null +++ b/apiserver/pkg/rbac/rbac_suite_test.go @@ -0,0 +1,33 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rbac_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" + + "github.com/projectcalico/calico/libcalico-go/lib/testutils" +) + +func init() { + testutils.HookLogrusForGinkgo() +} + +func TestRules(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "RBAC Suite") +} diff --git a/apiserver/pkg/registry/projectcalico/authorizer/authorizer.go b/apiserver/pkg/registry/projectcalico/authorizer/authorizer.go new file mode 100644 index 00000000000..05777bafb23 --- /dev/null +++ b/apiserver/pkg/registry/projectcalico/authorizer/authorizer.go @@ -0,0 +1,201 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package authorizer + +import ( + "context" + "fmt" + "sync" + + "k8s.io/klog/v2" + + calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "k8s.io/apimachinery/pkg/api/errors" + k8sauth "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/endpoints/filters" +) + +type TierAuthorizer interface { + // AuthorizeTierOperation checks whether the request is for a tiered policy, and if so checks + // whether the user us authorized to perform the operation. Returns a Forbidden error if the + // operation is not authorized. + AuthorizeTierOperation(ctx context.Context, policyName string, tierName string) error +} + +type authorizer struct { + k8sauth.Authorizer +} + +// Returns a new TierAuthorizer that uses the provided standard authorizer to perform the underlying +// lookups. +func NewTierAuthorizer(a k8sauth.Authorizer) TierAuthorizer { + return &authorizer{a} +} + +// AuthorizeTierOperation implements the TierAuthorizer interface. +func (a *authorizer) AuthorizeTierOperation( + ctx context.Context, + policyName string, + tierName string, +) error { + if a.Authorizer == nil { + klog.V(4).Info("No authorizer - allow operation") + return nil + } + + attributes, err := filters.GetAuthorizerAttributes(ctx) + if err != nil { + klog.Errorf("Unable to extract authorizer attributes: %s", err) + return err + } + + // Log the original authorizer attributes. + logAuthorizerAttributes(attributes) + + // We need to check whether the user is authorized to perform the action on the tier. + // resource, with a resource name of either: + // - .* (this is the wildcard syntax for any Calico policy within a tier) + // - . (this checks for a specific policy and tier, or fully wildcarded policy and tier) + // *and* has GET access for the tier. + // These requests can be performed in parallel. + wg := sync.WaitGroup{} + wg.Add(3) + + // Query GET access for the tier. + var decisionGetTier k8sauth.Decision + go func() { + defer wg.Done() + attrs := k8sauth.AttributesRecord{ + User: attributes.GetUser(), + Verb: "get", + Namespace: "", + APIGroup: attributes.GetAPIGroup(), + APIVersion: attributes.GetAPIVersion(), + Resource: "tiers", + Subresource: "", + Name: tierName, + ResourceRequest: true, + Path: "/apis/projectcalico.org/v3/tiers/" + tierName, + } + + klog.V(4).Infof("Checking authorization using tier resource type (user can get tier)") + logAuthorizerAttributes(attrs) + decisionGetTier, _, _ = a.Authorizer.Authorize(context.TODO(), attrs) + }() + + // Query required access to the tiered policy resource or tier wildcard resource. + var decisionPolicy, decisionTierWildcard k8sauth.Decision + var pathPrefix string + tierScopedResource := "tier." + attributes.GetResource() + if attributes.GetNamespace() == "" { + pathPrefix = "/apis/projectcalico.org/v3/" + tierScopedResource + } else { + pathPrefix = "/apis/projectcalico.org/v3/namespaces/" + attributes.GetNamespace() + "/" + tierScopedResource + } + go func() { + defer wg.Done() + path := pathPrefix + if attributes.GetName() != "" { + path = pathPrefix + "/" + attributes.GetName() + } + attrs := k8sauth.AttributesRecord{ + User: attributes.GetUser(), + Verb: attributes.GetVerb(), + Namespace: attributes.GetNamespace(), + APIGroup: attributes.GetAPIGroup(), + APIVersion: attributes.GetAPIVersion(), + Resource: tierScopedResource, + Subresource: attributes.GetSubresource(), + Name: attributes.GetName(), + ResourceRequest: true, + Path: path, + } + + klog.V(4).Infof("Checking authorization using tier scoped resource type (policy name match)") + logAuthorizerAttributes(attrs) + decisionPolicy, _, _ = a.Authorizer.Authorize(context.TODO(), attrs) + }() + go func() { + defer wg.Done() + name := tierName + ".*" + path := pathPrefix + "/" + name + attrs := k8sauth.AttributesRecord{ + User: attributes.GetUser(), + Verb: attributes.GetVerb(), + Namespace: attributes.GetNamespace(), + APIGroup: attributes.GetAPIGroup(), + APIVersion: attributes.GetAPIVersion(), + Resource: tierScopedResource, + Subresource: attributes.GetSubresource(), + Name: name, + ResourceRequest: true, + Path: path, + } + + klog.V(4).Infof("Checking authorization using tier scoped resource type (tier name match)") + logAuthorizerAttributes(attrs) + decisionTierWildcard, _, _ = a.Authorizer.Authorize(context.TODO(), attrs) + }() + + // Wait for the requests to complete. + wg.Wait() + + // If the user has GET access to the tier and either the policy match or tier wildcard match are authorized + // then allow the request. + if decisionGetTier == k8sauth.DecisionAllow && + (decisionPolicy == k8sauth.DecisionAllow || decisionTierWildcard == k8sauth.DecisionAllow) { + klog.Infof("Operation allowed") + return nil + } + + // Request is forbidden. + reason := forbiddenMessage(attributes, "tier", tierName, decisionGetTier) + klog.V(4).Infof("Operation on Calico tiered policy is forbidden: %v", reason) + return errors.NewForbidden(calico.Resource(attributes.GetResource()), policyName, fmt.Errorf("%s", reason)) +} + +// forbiddenMessage crafts the appropriate forbidden message for our special hierarchically owned resource types. This +// is largely copied from k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/errors.go +func forbiddenMessage(attributes k8sauth.Attributes, ownerResource, ownerName string, decisionGetOwner k8sauth.Decision) string { + username := "" + if user := attributes.GetUser(); user != nil { + username = user.GetName() + } + + resource := attributes.GetResource() + if group := attributes.GetAPIGroup(); len(group) > 0 { + resource = resource + "." + group + } + if subresource := attributes.GetSubresource(); len(subresource) > 0 { + resource = resource + "/" + subresource + } + + var msg string + if ns := attributes.GetNamespace(); len(ns) > 0 { + msg = fmt.Sprintf("User %q cannot %s %s in %s %q and namespace %q", username, attributes.GetVerb(), resource, ownerResource, ownerName, ns) + } else { + msg = fmt.Sprintf("User %q cannot %s %s in %s %q", username, attributes.GetVerb(), resource, ownerResource, ownerName) + } + + // If the user does not have get access to the tier, append additional text to the message. + if decisionGetOwner != k8sauth.DecisionAllow { + msg += fmt.Sprintf(" (user cannot get %s)", ownerResource) + } + return msg +} + +// logAuthorizerAttributes logs out the auth attributes. +func logAuthorizerAttributes(requestAttributes k8sauth.Attributes) { + if klog.V(4).Enabled() { + klog.Infof("Authorizer APIGroup: %s", requestAttributes.GetAPIGroup()) + klog.Infof("Authorizer APIVersion: %s", requestAttributes.GetAPIVersion()) + klog.Infof("Authorizer Name: %s", requestAttributes.GetName()) + klog.Infof("Authorizer Namespace: %s", requestAttributes.GetNamespace()) + klog.Infof("Authorizer Resource: %s", requestAttributes.GetResource()) + klog.Infof("Authorizer Subresource: %s", requestAttributes.GetSubresource()) + klog.Infof("Authorizer User: %s", requestAttributes.GetUser()) + klog.Infof("Authorizer Verb: %s", requestAttributes.GetVerb()) + klog.Infof("Authorizer Path: %s", requestAttributes.GetPath()) + } +} diff --git a/apiserver/pkg/registry/projectcalico/authorizer/authorizer_test.go b/apiserver/pkg/registry/projectcalico/authorizer/authorizer_test.go new file mode 100644 index 00000000000..81b3efba553 --- /dev/null +++ b/apiserver/pkg/registry/projectcalico/authorizer/authorizer_test.go @@ -0,0 +1,444 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package authorizer_test + +import ( + "context" + "testing" + + "k8s.io/apiserver/pkg/authentication/user" + k8sauth "k8s.io/apiserver/pkg/authorization/authorizer" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/authorizer" +) + +type testAuth struct { + t *testing.T + lookup map[k8sauth.Attributes]k8sauth.Decision +} + +func (t *testAuth) Authorize(ctx context.Context, a k8sauth.Attributes) (authorized k8sauth.Decision, reason string, err error) { + d, ok := t.lookup[a] + if !ok { + t.t.Fatalf("Unexpected authz attributes: %v\n%v", a, t.lookup) + } + // The authorization code only uses the Decision, so we can return arbitrary reason and error responses. + return d, "", nil +} + +var ( + // Test users and attributes that are used for multiple tests. + testUser = &user.DefaultInfo{ + Name: "testuser", + UID: "abced", + Groups: []string{"group1", "group2"}, + } + + getTierAttr = k8sauth.AttributesRecord{ + User: testUser, + Verb: "get", + Namespace: "", + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "tiers", + Subresource: "", + Name: "test-tier", + ResourceRequest: true, + Path: "/apis/projectcalico.org/v3/tiers/test-tier", + } +) + +// createGnpAttr returns the expected attributes for a GNP +func createGnpAttr(verb string) k8sauth.Attributes { + ar := k8sauth.AttributesRecord{ + User: testUser, + Verb: verb, + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "tier.globalnetworkpolicies", + Name: "test-tier.test-gnp", + ResourceRequest: true, + Path: "/apis/projectcalico.org/v3/tier.globalnetworkpolicies/test-tier.test-gnp", + } + if verb == "list" || verb == "create" { + ar.Path = "/apis/projectcalico.org/v3/tier.globalnetworkpolicies" + ar.Name = "" + } + return ar +} + +// createGnpTierAttr returns the expected attributes for a tier wildcard GNP match +func createGnpTierAttr(verb string) k8sauth.Attributes { + return k8sauth.AttributesRecord{ + User: testUser, + Verb: verb, + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "tier.globalnetworkpolicies", + Name: "test-tier.*", + ResourceRequest: true, + Path: "/apis/projectcalico.org/v3/tier.globalnetworkpolicies/test-tier.*", + } +} + +// createNpAttr returns the expected attributes for a NP +func createNpAttr(verb string) k8sauth.Attributes { + ar := k8sauth.AttributesRecord{ + User: testUser, + Verb: verb, + Namespace: "test-namespace", + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "tier.networkpolicies", + Name: "test-tier.test-np", + ResourceRequest: true, + Path: "/apis/projectcalico.org/v3/namespaces/test-namespace/tier.networkpolicies/test-tier.test-np", + } + if verb == "list" || verb == "create" { + ar.Path = "/apis/projectcalico.org/v3/namespaces/test-namespace/tier.networkpolicies" + ar.Name = "" + } + return ar +} + +// createNpTierAttr returns the expected attributes for a tier wildcard NP match +func createNpTierAttr(verb string) k8sauth.Attributes { + return k8sauth.AttributesRecord{ + User: testUser, + Verb: verb, + Namespace: "test-namespace", + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "tier.networkpolicies", + Name: "test-tier.*", + ResourceRequest: true, + Path: "/apis/projectcalico.org/v3/namespaces/test-namespace/tier.networkpolicies/test-tier.*", + } +} + +// createGnpContext returns the expected attributes for a tier wildcard NP match +func createGnpContext(verb string) context.Context { + ctx := genericapirequest.NewContext() + ctx = genericapirequest.WithUser(ctx, testUser) + ri := &genericapirequest.RequestInfo{ + IsResourceRequest: true, + Path: "/apis/projectcalico.org/v3/globalnetworkpolicies/test-tier.test-gnp", + Verb: verb, + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "globalnetworkpolicies", + Name: "test-tier.test-gnp", + } + if verb == "list" || verb == "create" { + ri.Name = "" + ri.Path = "/apis/projectcalico.org/v3/globalnetworkpolicies" + } + ctx = genericapirequest.WithRequestInfo(ctx, ri) + return ctx +} + +// createNpContext returns the expected attributes for a tier wildcard NP match +func createNpContext(verb string) context.Context { + ctx := genericapirequest.NewContext() + ctx = genericapirequest.WithUser(ctx, testUser) + ctx = genericapirequest.WithNamespace(ctx, "test-namespace") + ri := &genericapirequest.RequestInfo{ + IsResourceRequest: true, + Path: "/apis/projectcalico.org/v3/namespaces/test-namespace/networkpolicies/test-tier.test-np", + Verb: verb, + APIGroup: "projectcalico.org", + APIVersion: "v3", + Resource: "networkpolicies", + Namespace: "test-namespace", + Name: "test-tier.test-np", + } + if verb == "list" || verb == "create" { + ri.Name = "" + ri.Path = "/apis/projectcalico.org/v3/namespaces/test-namespace/networkpolicies" + } + ctx = genericapirequest.WithRequestInfo(ctx, ri) + return ctx +} + +func createNpError(verb string, cannotGetTier bool) string { + msg := "networkpolicies.projectcalico.org " + if verb != "list" { + msg += "\"test-tier.test-np\" " + } + msg += "is forbidden: User \"testuser\" cannot " + verb + + " networkpolicies.projectcalico.org in tier \"test-tier\" and namespace \"test-namespace\"" + if cannotGetTier { + msg += " (user cannot get tier)" + } + return msg +} + +func createGnpError(verb string, cannotGetTier bool) string { + msg := "globalnetworkpolicies.projectcalico.org " + if verb != "list" { + msg += "\"test-tier.test-gnp\" " + } + msg += "is forbidden: User \"testuser\" cannot " + verb + + " globalnetworkpolicies.projectcalico.org in tier \"test-tier\"" + if cannotGetTier { + msg += " (user cannot get tier)" + } + return msg +} + +func TestNetworkPolicyNoTierGet(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionDeny, + createNpAttr("create"): k8sauth.DecisionAllow, + createNpTierAttr("create"): k8sauth.DecisionAllow, + createNpAttr("list"): k8sauth.DecisionAllow, + createNpTierAttr("list"): k8sauth.DecisionAllow, + createNpAttr("delete"): k8sauth.DecisionAllow, + createNpTierAttr("delete"): k8sauth.DecisionAllow, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("create"), "test-tier.test-np", "test-tier", + ); err == nil { + t.Fatalf("No error returned creating NP when tier GET not permitted") + } else if err.Error() != createNpError("create", true) { + t.Fatalf("Incorrect error message creating NP when tier GET not permitted: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("delete"), "test-tier.test-np", "test-tier", + ); err == nil { + t.Fatalf("No error returned deleting NP when tier GET not permitted") + } else if err.Error() != createNpError("delete", true) { + t.Fatalf("Incorrect error message deleting NP when tier GET not permitted: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("list"), "", "test-tier", + ); err == nil { + t.Fatalf("No error returned listing NP when tier GET not permitted") + } else if err.Error() != createNpError("list", true) { + t.Fatalf("Incorrect error message listing NP when tier GET not permitted: %v", err) + } +} + +func TestGlobalNetworkPolicyNoTierGet(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionDeny, + createGnpAttr("create"): k8sauth.DecisionAllow, + createGnpTierAttr("create"): k8sauth.DecisionAllow, + createGnpAttr("list"): k8sauth.DecisionAllow, + createGnpTierAttr("list"): k8sauth.DecisionAllow, + createGnpAttr("get"): k8sauth.DecisionAllow, + createGnpTierAttr("get"): k8sauth.DecisionAllow, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("create"), "test-tier.test-gnp", "test-tier", + ); err == nil { + t.Fatalf("No error returned creating GNP when tier GET not permitted") + } else if err.Error() != createGnpError("create", true) { + t.Fatalf("Incorrect error message creating GNP when tier GET not permitted: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("get"), "test-tier.test-gnp", "test-tier", + ); err == nil { + t.Fatalf("No error returned getting GNP when tier GET not permitted") + } else if err.Error() != createGnpError("get", true) { + t.Fatalf("Incorrect error message getting GNP when tier GET not permitted: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("list"), "", "test-tier", + ); err == nil { + t.Fatalf("No error returned listing GNP when tier GET not permitted") + } else if err.Error() != createGnpError("list", true) { + t.Fatalf("Incorrect error message listing GNP when tier GET not permitted: %v", err) + } +} + +func TestNetworkPolicyTierWildcard(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionAllow, + createNpAttr("create"): k8sauth.DecisionDeny, + createNpTierAttr("create"): k8sauth.DecisionAllow, + createNpAttr("list"): k8sauth.DecisionDeny, + createNpTierAttr("list"): k8sauth.DecisionAllow, + createNpAttr("delete"): k8sauth.DecisionDeny, + createNpTierAttr("delete"): k8sauth.DecisionAllow, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("create"), "test-tier.test-np", "test-tier", + ); err != nil { + t.Fatalf("Error returned creating NP when tier GET and wildcard match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("delete"), "test-tier.test-np", "test-tier", + ); err != nil { + t.Fatalf("Error returned deleting NP when tier GET and wildcard match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("list"), "", "test-tier", + ); err != nil { + t.Fatalf("Error returned listing NP when tier GET and wildcard match permit the request: %v", err) + } +} + +func TestGlobalNetworkPolicyTierWildcard(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionAllow, + createGnpAttr("create"): k8sauth.DecisionDeny, + createGnpTierAttr("create"): k8sauth.DecisionAllow, + createGnpAttr("list"): k8sauth.DecisionDeny, + createGnpTierAttr("list"): k8sauth.DecisionAllow, + createGnpAttr("delete"): k8sauth.DecisionDeny, + createGnpTierAttr("delete"): k8sauth.DecisionAllow, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("create"), "test-tier.test-gnp", "test-tier", + ); err != nil { + t.Fatalf("Error returned creating GNP when tier GET and wildcard match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("delete"), "test-tier.test-gnp", "test-tier", + ); err != nil { + t.Fatalf("Error returned deleting GNP when tier GET and wildcard match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("list"), "", "test-tier", + ); err != nil { + t.Fatalf("Error returned listing GNP when tier GET and wildcard match permit the request: %v", err) + } +} + +func TestNetworkPolicyByName(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionAllow, + createNpAttr("create"): k8sauth.DecisionAllow, + createNpTierAttr("create"): k8sauth.DecisionDeny, + createNpAttr("list"): k8sauth.DecisionAllow, + createNpTierAttr("list"): k8sauth.DecisionDeny, + createNpAttr("get"): k8sauth.DecisionAllow, + createNpTierAttr("get"): k8sauth.DecisionDeny, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("create"), "test-tier.test-np", "test-tier", + ); err != nil { + t.Fatalf("Error returned creating NP when tier GET and named match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("get"), "test-tier.test-np", "test-tier", + ); err != nil { + t.Fatalf("Error returned getting NP when tier GET and named match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("list"), "", "test-tier", + ); err != nil { + t.Fatalf("Error returned listing NP when tier GET and named match permit the request: %v", err) + } +} + +func TestGlobalNetworkPolicyByName(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionAllow, + createGnpAttr("create"): k8sauth.DecisionAllow, + createGnpTierAttr("create"): k8sauth.DecisionDeny, + createGnpAttr("list"): k8sauth.DecisionAllow, + createGnpTierAttr("list"): k8sauth.DecisionDeny, + createGnpAttr("get"): k8sauth.DecisionAllow, + createGnpTierAttr("get"): k8sauth.DecisionDeny, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("create"), "test-tier.test-gnp", "test-tier", + ); err != nil { + t.Fatalf("Error returned creating GNP when tier GET and named match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("get"), "test-tier.test-gnp", "test-tier", + ); err != nil { + t.Fatalf("Error returned getting GNP when tier GET and named match permit the request: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("list"), "", "test-tier", + ); err != nil { + t.Fatalf("Error returned listing GNP when tier GET and named match permit the request: %v", err) + } +} + +func TestNetworkPolicyDenied(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionAllow, + createNpAttr("create"): k8sauth.DecisionDeny, + createNpTierAttr("create"): k8sauth.DecisionDeny, + createNpAttr("list"): k8sauth.DecisionDeny, + createNpTierAttr("list"): k8sauth.DecisionDeny, + createNpAttr("delete"): k8sauth.DecisionDeny, + createNpTierAttr("delete"): k8sauth.DecisionDeny, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("create"), "test-tier.test-np", "test-tier", + ); err == nil { + t.Fatalf("No error returned creating NP when not permitted by NP RBAC") + } else if err.Error() != createNpError("create", false) { + t.Fatalf("Incorrect error message creating NP when not permitted by NP RBAC: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("delete"), "test-tier.test-np", "test-tier", + ); err == nil { + t.Fatalf("No error returned deleting NP when not permitted by NP RBAC") + } else if err.Error() != createNpError("delete", false) { + t.Fatalf("Incorrect error message deleting NP when not permitted by NP RBAC: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createNpContext("list"), "", "test-tier", + ); err == nil { + t.Fatalf("No error returned listing NP when not permitted by NP RBAC") + } else if err.Error() != createNpError("list", false) { + t.Fatalf("Incorrect error message listing NP when not permitted by NP RBAC: %v", err) + } +} + +func TestGlobalNetworkPolicyDenied(t *testing.T) { + ta := &testAuth{t, map[k8sauth.Attributes]k8sauth.Decision{ + getTierAttr: k8sauth.DecisionAllow, + createGnpAttr("create"): k8sauth.DecisionDeny, + createGnpTierAttr("create"): k8sauth.DecisionDeny, + createGnpAttr("list"): k8sauth.DecisionDeny, + createGnpTierAttr("list"): k8sauth.DecisionDeny, + createGnpAttr("get"): k8sauth.DecisionDeny, + createGnpTierAttr("get"): k8sauth.DecisionDeny, + }} + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("create"), "test-tier.test-gnp", "test-tier", + ); err == nil { + t.Fatalf("No error returned creating GNP when not permitted by GNP RBAC") + } else if err.Error() != createGnpError("create", false) { + t.Fatalf("Incorrect error message creating GNP when not permitted by NP RBAC: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("get"), "test-tier.test-gnp", "test-tier", + ); err == nil { + t.Fatalf("No error returned deleting GNP when not permitted by GNP RBAC") + } else if err.Error() != createGnpError("get", false) { + t.Fatalf("Incorrect error message getting GNP when not permitted by NP RBAC: %v", err) + } + + if err := authorizer.NewTierAuthorizer(ta).AuthorizeTierOperation( + createGnpContext("list"), "", "test-tier", + ); err == nil { + t.Fatalf("No error returned listing GNP when not permitted by GNP RBAC") + } else if err.Error() != createGnpError("list", false) { + t.Fatalf("Incorrect error message listing GNP when not permitted by NP RBAC: %v", err) + } +} diff --git a/apiserver/pkg/registry/projectcalico/globalpolicy/storage.go b/apiserver/pkg/registry/projectcalico/globalpolicy/storage.go index a0cf3c0d870..f00f0d27f72 100644 --- a/apiserver/pkg/registry/projectcalico/globalpolicy/storage.go +++ b/apiserver/pkg/registry/projectcalico/globalpolicy/storage.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,10 @@ import ( calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/apiserver/pkg/rbac" + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/authorizer" "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/server" + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/util" "k8s.io/apimachinery/pkg/api/meta" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" @@ -35,6 +38,8 @@ import ( // rest implements a RESTStorage for API services against etcd type REST struct { *genericregistry.Store + rbac.CalicoResourceLister + authorizer authorizer.TierAuthorizer shortNames []string } @@ -49,7 +54,7 @@ func NewList() runtime.Object { } // NewREST returns a RESTStorage object that will work against API services. -func NewREST(scheme *runtime.Scheme, opts server.Options) (*REST, error) { +func NewREST(scheme *runtime.Scheme, opts server.Options, calicoResourceLister rbac.CalicoResourceLister) (*REST, error) { strategy := NewStrategy(scheme) prefix := "/" + opts.ResourcePrefix() @@ -98,32 +103,69 @@ func NewREST(scheme *runtime.Scheme, opts server.Options) (*REST, error) { Storage: storageInterface, DestroyFunc: dFunc, } - return &REST{store, opts.ShortNames}, nil + + return &REST{store, calicoResourceLister, authorizer.NewTierAuthorizer(opts.Authorizer), []string{}}, nil } func (r *REST) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { + err := util.EnsureTierSelector(ctx, options, r.authorizer, r.CalicoResourceLister) + if err != nil { + return nil, err + } + return r.Store.List(ctx, options) } func (r *REST) Create(ctx context.Context, obj runtime.Object, val rest.ValidateObjectFunc, createOpt *metav1.CreateOptions) (runtime.Object, error) { + policy := obj.(*calico.GlobalNetworkPolicy) + // Is Tier prepended. If not prepend default? + tierName, _ := util.GetTierFromPolicyName(policy.Name) + err := r.authorizer.AuthorizeTierOperation(ctx, policy.Name, tierName) + if err != nil { + return nil, err + } + return r.Store.Create(ctx, obj, val, createOpt) } func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { + tierName, _ := util.GetTierFromPolicyName(name) + err := r.authorizer.AuthorizeTierOperation(ctx, name, tierName) + if err != nil { + return nil, false, err + } + return r.Store.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) } // Get retrieves the item from storage. func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { + tierName, _ := util.GetTierFromPolicyName(name) + err := r.authorizer.AuthorizeTierOperation(ctx, name, tierName) + if err != nil { + return nil, err + } + return r.Store.Get(ctx, name, options) } func (r *REST) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { + tierName, _ := util.GetTierFromPolicyName(name) + err := r.authorizer.AuthorizeTierOperation(ctx, name, tierName) + if err != nil { + return nil, false, err + } + return r.Store.Delete(ctx, name, deleteValidation, options) } func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { + err := util.EnsureTierSelector(ctx, options, r.authorizer, r.CalicoResourceLister) + if err != nil { + return nil, err + } + return r.Store.Watch(ctx, options) } diff --git a/apiserver/pkg/registry/projectcalico/globalpolicy/strategy.go b/apiserver/pkg/registry/projectcalico/globalpolicy/strategy.go index 0f7c7550a11..faa0786118b 100644 --- a/apiserver/pkg/registry/projectcalico/globalpolicy/strategy.go +++ b/apiserver/pkg/registry/projectcalico/globalpolicy/strategy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package globalpolicy import ( "context" "fmt" + "strings" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" @@ -43,15 +44,40 @@ func (policyStrategy) NamespaceScoped() bool { } func (policyStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { + obj.(*calico.GlobalNetworkPolicy).Name = canonicalizePolicyName(obj) } func (policyStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { + obj.(*calico.GlobalNetworkPolicy).Name = canonicalizePolicyName(old) +} + +func canonicalizePolicyName(obj runtime.Object) string { + // Policies without a tier prepended to their name should have the tier prepended. + // It's possible for a user to send a policy with one of two name formats: + // + // - "tier.policy" + // - "policy" + // + // The logic below handles canonicalizing the name to the former. + tier := "default" + if oldPolicy, ok := obj.(*calico.GlobalNetworkPolicy); ok && oldPolicy.Spec.Tier != "" { + tier = oldPolicy.Spec.Tier + } + + policy := obj.(*calico.GlobalNetworkPolicy) + if len(strings.Split(policy.Name, ".")) == 1 { + // Tier is not included in the name - add it. + return tier + "." + policy.Name + } + + // Name already includes the tier. + return policy.Name } func (policyStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { return field.ErrorList{} // TODO: - //return validation.ValidatePolicy(obj.(*calico.Policy)) + // return validation.ValidatePolicy(obj.(*calico.Policy)) } func (policyStrategy) AllowCreateOnUpdate() bool { @@ -101,5 +127,6 @@ func MatchPolicy(label labels.Selector, field fields.Selector) storage.Selection func PolicyToSelectableFields(obj *calico.GlobalNetworkPolicy) fields.Set { return fields.Set{ "metadata.name": obj.Name, + "spec.tier": obj.Spec.Tier, } } diff --git a/apiserver/pkg/registry/projectcalico/networkpolicy/storage.go b/apiserver/pkg/registry/projectcalico/networkpolicy/storage.go index feac5ebf450..61f2c2a20e4 100644 --- a/apiserver/pkg/registry/projectcalico/networkpolicy/storage.go +++ b/apiserver/pkg/registry/projectcalico/networkpolicy/storage.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,10 @@ import ( calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/apiserver/pkg/rbac" + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/authorizer" "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/server" + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/util" "k8s.io/apimachinery/pkg/api/meta" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" @@ -35,6 +38,8 @@ import ( // rest implements a RESTStorage for API services against etcd type REST struct { *genericregistry.Store + rbac.CalicoResourceLister + authorizer authorizer.TierAuthorizer shortNames []string } @@ -52,7 +57,7 @@ func NewList() runtime.Object { } // NewREST returns a RESTStorage object that will work against API services. -func NewREST(scheme *runtime.Scheme, opts server.Options) (*REST, error) { +func NewREST(scheme *runtime.Scheme, opts server.Options, calicoResourceLister rbac.CalicoResourceLister) (*REST, error) { strategy := NewStrategy(scheme) prefix := "/" + opts.ResourcePrefix() @@ -98,31 +103,68 @@ func NewREST(scheme *runtime.Scheme, opts server.Options) (*REST, error) { DestroyFunc: dFunc, } - return &REST{Store: store, shortNames: opts.ShortNames}, nil + return &REST{store, calicoResourceLister, authorizer.NewTierAuthorizer(opts.Authorizer), []string{}}, nil } func (r *REST) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { + err := util.EnsureTierSelector(ctx, options, r.authorizer, r.CalicoResourceLister) + if err != nil { + return nil, err + } + return r.Store.List(ctx, options) } func (r *REST) Create(ctx context.Context, obj runtime.Object, val rest.ValidateObjectFunc, createOpt *metav1.CreateOptions) (runtime.Object, error) { + policy := obj.(*calico.NetworkPolicy) + // Is Tier prepended. If not prepend default? + tierName, _ := util.GetTierFromPolicyName(policy.Name) + err := r.authorizer.AuthorizeTierOperation(ctx, policy.Name, tierName) + if err != nil { + return nil, err + } + return r.Store.Create(ctx, obj, val, createOpt) } func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { + tierName, _ := util.GetTierFromPolicyName(name) + err := r.authorizer.AuthorizeTierOperation(ctx, name, tierName) + if err != nil { + return nil, false, err + } + return r.Store.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) } +// Get retrieves the item from storage. func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { + tierName, _ := util.GetTierFromPolicyName(name) + err := r.authorizer.AuthorizeTierOperation(ctx, name, tierName) + if err != nil { + return nil, err + } + return r.Store.Get(ctx, name, options) } func (r *REST) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { + tierName, _ := util.GetTierFromPolicyName(name) + err := r.authorizer.AuthorizeTierOperation(ctx, name, tierName) + if err != nil { + return nil, false, err + } + return r.Store.Delete(ctx, name, deleteValidation, options) } func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { + err := util.EnsureTierSelector(ctx, options, r.authorizer, r.CalicoResourceLister) + if err != nil { + return nil, err + } + return r.Store.Watch(ctx, options) } diff --git a/apiserver/pkg/registry/projectcalico/networkpolicy/strategy.go b/apiserver/pkg/registry/projectcalico/networkpolicy/strategy.go index 5f4ac97b854..a64bff4131f 100644 --- a/apiserver/pkg/registry/projectcalico/networkpolicy/strategy.go +++ b/apiserver/pkg/registry/projectcalico/networkpolicy/strategy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package networkpolicy import ( "context" "fmt" + "strings" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" @@ -43,14 +44,39 @@ func (policyStrategy) NamespaceScoped() bool { } func (policyStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { + obj.(*calico.NetworkPolicy).Name = canonicalizePolicyName(obj) } func (policyStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { + obj.(*calico.NetworkPolicy).Name = canonicalizePolicyName(old) +} + +func canonicalizePolicyName(obj runtime.Object) string { + // Policies without a tier prepended to their name should have the tier prepended. + // It's possible for a user to send a policy with one of two name formats: + // + // - "tier.policy" + // - "policy" + // + // The logic below handles canonicalizing the name to the former. + tier := "default" + if oldPolicy, ok := obj.(*calico.NetworkPolicy); ok && oldPolicy.Spec.Tier != "" { + tier = oldPolicy.Spec.Tier + } + + policy := obj.(*calico.NetworkPolicy) + if len(strings.Split(policy.Name, ".")) == 1 { + // Tier is not included in the name - add it. + return tier + "." + policy.Name + } + + // Name already includes the tier. + return policy.Name } func (policyStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { return field.ErrorList{} - //return validation.ValidatePolicy(obj.(*calico.Policy)) + // return validation.ValidatePolicy(obj.(*calico.Policy)) } func (policyStrategy) AllowCreateOnUpdate() bool { @@ -100,5 +126,6 @@ func PolicyToSelectableFields(obj *calico.NetworkPolicy) fields.Set { return fields.Set{ "metadata.name": obj.Name, "metadata.namespace": obj.Namespace, + "spec.tier": obj.Spec.Tier, } } diff --git a/apiserver/pkg/registry/projectcalico/rest/storage_calico.go b/apiserver/pkg/registry/projectcalico/rest/storage_calico.go index f75eb5a2141..39ec9f66477 100644 --- a/apiserver/pkg/registry/projectcalico/rest/storage_calico.go +++ b/apiserver/pkg/registry/projectcalico/rest/storage_calico.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/apiserver/pkg/rbac" calicobgpconfiguration "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/bgpconfiguration" calicobgpfilter "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/bgpfilter" calicobgppeer "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/bgppeer" @@ -42,6 +43,7 @@ import ( caliconetworkset "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/networkset" calicoprofile "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/profile" "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/server" + calicotier "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/tier" calicostorage "github.com/projectcalico/calico/apiserver/pkg/storage/calico" "github.com/projectcalico/calico/apiserver/pkg/storage/etcd" ) @@ -57,6 +59,7 @@ func (p RESTStorageProvider) NewV3Storage( scheme *runtime.Scheme, restOptionsGetter generic.RESTOptionsGetter, authorizer authorizer.Authorizer, + calicoLister rbac.CalicoResourceLister, ) (map[string]rest.Storage, error) { policyRESTOptions, err := restOptionsGetter.GetRESTOptions(calico.Resource("networkpolicies")) if err != nil { @@ -102,6 +105,28 @@ func (p RESTStorageProvider) NewV3Storage( []string{"netsets"}, ) + tierRESTOptions, err := restOptionsGetter.GetRESTOptions(calico.Resource("tiers")) + if err != nil { + return nil, err + } + tierOpts := server.NewOptions( + etcd.Options{ + RESTOptions: tierRESTOptions, + Capacity: 1000, + ObjectType: calicotier.EmptyObject(), + ScopeStrategy: calicotier.NewStrategy(scheme), + NewListFunc: calicotier.NewList, + GetAttrsFunc: calicotier.GetAttrs, + Trigger: nil, + }, + calicostorage.Options{ + RESTOptions: tierRESTOptions, + }, + p.StorageType, + authorizer, + []string{}, + ) + gpolicyRESTOptions, err := restOptionsGetter.GetRESTOptions(calico.Resource("globalnetworkpolicies")) if err != nil { return nil, err @@ -433,8 +458,9 @@ func (p RESTStorageProvider) NewV3Storage( ) storage := map[string]rest.Storage{} - storage["networkpolicies"] = rESTInPeace(calicopolicy.NewREST(scheme, *policyOpts)) - storage["globalnetworkpolicies"] = rESTInPeace(calicogpolicy.NewREST(scheme, *gpolicyOpts)) + storage["tiers"] = rESTInPeace(calicotier.NewREST(scheme, *tierOpts)) + storage["networkpolicies"] = rESTInPeace(calicopolicy.NewREST(scheme, *policyOpts, calicoLister)) + storage["globalnetworkpolicies"] = rESTInPeace(calicogpolicy.NewREST(scheme, *gpolicyOpts, calicoLister)) storage["globalnetworksets"] = rESTInPeace(calicognetworkset.NewREST(scheme, *gNetworkSetOpts)) storage["networksets"] = rESTInPeace(caliconetworkset.NewREST(scheme, *networksetOpts)) storage["hostendpoints"] = rESTInPeace(calicohostendpoint.NewREST(scheme, *hostEndpointOpts)) diff --git a/apiserver/pkg/registry/projectcalico/tier/storage.go b/apiserver/pkg/registry/projectcalico/tier/storage.go new file mode 100644 index 00000000000..195f96ed208 --- /dev/null +++ b/apiserver/pkg/registry/projectcalico/tier/storage.go @@ -0,0 +1,96 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing persmissions and +// limitations under the License. + +package tier + +import ( + calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/server" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/registry/generic/registry" + genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" +) + +// REST implements a RESTStorage for API services against etcd +type REST struct { + *genericregistry.Store +} + +// EmptyObject returns an empty instance +func EmptyObject() runtime.Object { + return &calico.Tier{} +} + +// NewList returns a new shell of a binding list +func NewList() runtime.Object { + return &calico.TierList{} +} + +// NewREST returns a RESTStorage object that will work against API services. +func NewREST(scheme *runtime.Scheme, opts server.Options) (*REST, error) { + strategy := NewStrategy(scheme) + + prefix := "/" + opts.ResourcePrefix() + // We adapt the store's keyFunc so that we can use it with the StorageDecorator + // without making any assumptions about where objects are stored in etcd + keyFunc := func(obj runtime.Object) (string, error) { + accessor, err := meta.Accessor(obj) + if err != nil { + return "", err + } + return registry.NoNamespaceKeyFunc( + genericapirequest.NewContext(), + prefix, + accessor.GetName(), + ) + } + storageInterface, dFunc, err := opts.GetStorage( + prefix, + keyFunc, + strategy, + func() runtime.Object { return &calico.Tier{} }, + func() runtime.Object { return &calico.TierList{} }, + GetAttrs, + nil, + nil, + ) + if err != nil { + return nil, err + } + store := &genericregistry.Store{ + NewFunc: func() runtime.Object { return &calico.Tier{} }, + NewListFunc: func() runtime.Object { return &calico.TierList{} }, + KeyRootFunc: opts.KeyRootFunc(false), + KeyFunc: opts.KeyFunc(false), + ObjectNameFunc: func(obj runtime.Object) (string, error) { + return obj.(*calico.Tier).Name, nil + }, + PredicateFunc: MatchTier, + DefaultQualifiedResource: calico.Resource("tiers"), + + CreateStrategy: strategy, + UpdateStrategy: strategy, + DeleteStrategy: strategy, + EnableGarbageCollection: true, + + Storage: storageInterface, + DestroyFunc: dFunc, + } + + return &REST{store}, nil +} diff --git a/apiserver/pkg/registry/projectcalico/tier/strategy.go b/apiserver/pkg/registry/projectcalico/tier/strategy.go new file mode 100644 index 00000000000..14ea6f3d203 --- /dev/null +++ b/apiserver/pkg/registry/projectcalico/tier/strategy.go @@ -0,0 +1,102 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing persmissions and +// limitations under the License. + +package tier + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/registry/generic" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/names" + + calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" +) + +type apiServerStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +// NewStrategy returns a new NamespaceScopedStrategy for instances +func NewStrategy(typer runtime.ObjectTyper) apiServerStrategy { + return apiServerStrategy{typer, names.SimpleNameGenerator} +} + +func (apiServerStrategy) NamespaceScoped() bool { + return false +} + +func (apiServerStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { +} + +func (apiServerStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { +} + +func (apiServerStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + return field.ErrorList{} + // return validation.ValidateTier(obj.(*calico.Tier)) +} + +func (apiServerStrategy) AllowCreateOnUpdate() bool { + return false +} + +func (apiServerStrategy) AllowUnconditionalUpdate() bool { + return false +} + +func (apiServerStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { + return []string{} +} + +func (apiServerStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { + return []string{} +} + +func (apiServerStrategy) Canonicalize(obj runtime.Object) { +} + +func (apiServerStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return field.ErrorList{} + // return validation.ValidateTierUpdate(obj.(*calico.Tier), old.(*calico.Tier)) +} + +func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { + apiserver, ok := obj.(*calico.Tier) + if !ok { + return nil, nil, fmt.Errorf("given object is not a Tier") + } + return labels.Set(apiserver.ObjectMeta.Labels), TierToSelectableFields(apiserver), nil +} + +// MatchTier is the filter used by the generic etcd backend to watch events +// from etcd to clients of the apiserver only interested in specific labels/fields. +func MatchTier(label labels.Selector, field fields.Selector) storage.SelectionPredicate { + return storage.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: GetAttrs, + } +} + +// TierToSelectableFields returns a field set that represents the object. +func TierToSelectableFields(obj *calico.Tier) fields.Set { + return generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false) +} diff --git a/apiserver/pkg/registry/projectcalico/util/rbac.go b/apiserver/pkg/registry/projectcalico/util/rbac.go new file mode 100644 index 00000000000..ad8438fd519 --- /dev/null +++ b/apiserver/pkg/registry/projectcalico/util/rbac.go @@ -0,0 +1,154 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package util + +import ( + "context" + "fmt" + "strings" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apiserver/pkg/endpoints/filters" + + "github.com/projectcalico/calico/apiserver/pkg/rbac" + "github.com/projectcalico/calico/apiserver/pkg/registry/projectcalico/authorizer" + + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" + "k8s.io/apimachinery/pkg/selection" +) + +const ( + policyDelim = "." +) + +// EnsureTierSelector parses the given options and ensures the correct tier selector is set. +// It first checks the input selector, if given. Otherwise, it uses a tier selector based on the user's permissions. +func EnsureTierSelector(ctx context.Context, options *metainternalversion.ListOptions, authorizer authorizer.TierAuthorizer, calicoResourceLister rbac.CalicoResourceLister) error { + // Get tiers from the selector passed by the user, if any. + tiers, err := getTiersFromSelector(options) + if err != nil { + return err + } + if tiers == nil { + // No tiers were given - default to the tiers the user has permissions to see. + tiers, err = getAuthorizedTiers(ctx, authorizer, calicoResourceLister) + if err != nil { + return err + } + + // Update the selector on the input options to include the new tiers. + tierSelector, err := buildSelectorFromTiers(tiers) + if err != nil { + return err + } + + if options.LabelSelector == nil { + options.LabelSelector = labels.NewSelector() + } + options.LabelSelector = options.LabelSelector.Add(*tierSelector) + } else { + err = authorizeTiers(ctx, tiers, authorizer) + if err != nil { + return err + } + } + + return nil +} + +// getTiersFromSelector extracts the tiers set in the ListOptions selectors, and ensures valid list operator +func getTiersFromSelector(options *metainternalversion.ListOptions) ([]string, error) { + if options.FieldSelector != nil { + requirements := options.FieldSelector.Requirements() + for _, requirement := range requirements { + if requirement.Field == "spec.tier" { + if requirement.Operator == selection.Equals || + requirement.Operator == selection.DoubleEquals { + return []string{requirement.Value}, nil + } + return nil, fmt.Errorf("Non equal selector operator not supported for field spec.tier") + } + } + } + + if options.LabelSelector != nil { + requirements, _ := options.LabelSelector.Requirements() + for _, requirement := range requirements { + if requirement.Key() == "projectcalico.org/tier" { + if requirement.Operator() == selection.In { + return requirement.Values().List(), nil + } + if len(requirement.Values()) > 1 { + return nil, fmt.Errorf("Non IN multi-valued selector not supported for label projectcalico.org/tier") + } + tierName, ok := requirement.Values().PopAny() + if ok && (requirement.Operator() == selection.Equals || + requirement.Operator() == selection.DoubleEquals) { + return []string{tierName}, nil + } + return nil, fmt.Errorf("Non equal selector operator not supported for label projectcalico.org/tier") + } + } + } + + // Reaching here implies tier hasn't been explicitly set as part of the selectors. We set the tier to all tiers available to user + return nil, nil +} + +// getAuthorizedTiers gets all the available Tiers to the user +func getAuthorizedTiers(ctx context.Context, authorizer authorizer.TierAuthorizer, calicoResourceLister rbac.CalicoResourceLister) ([]string, error) { + tiers, err := calicoResourceLister.ListTiers() + if err != nil { + return nil, err + } + var allowedTiers []string + + for _, tier := range tiers { + err := authorizer.AuthorizeTierOperation(ctx, "", tier.Name) + if err == nil { + allowedTiers = append(allowedTiers, tier.Name) + } + } + + if len(allowedTiers) == 0 && len(tiers) != 0 { + attributes, err := filters.GetAuthorizerAttributes(ctx) + if err != nil { + return nil, err + } + return nil, errors.NewForbidden(v3.Resource(attributes.GetResource()), "", fmt.Errorf("Operation on Calico tiered policy is forbidden")) + } + + return allowedTiers, nil +} + +// authorizeTiers ensures that the user has access to all the supplied Tiers +func authorizeTiers(ctx context.Context, tiers []string, authorizer authorizer.TierAuthorizer) error { + for _, tier := range tiers { + err := authorizer.AuthorizeTierOperation(ctx, "", tier) + if err != nil { + return err + } + } + + return nil +} + +func buildSelectorFromTiers(tiers []string) (*labels.Requirement, error) { + requirement, err := labels.NewRequirement("projectcalico.org/tier", selection.In, tiers) + if err != nil { + return nil, err + } + + return requirement, nil +} + +// GetTierFromPolicyName extracts the Tier name from the policy name. +func GetTierFromPolicyName(policyName string) (string, string) { + policySlice := strings.Split(policyName, policyDelim) + if len(policySlice) < 2 { + return "default", policySlice[0] + } + return policySlice[0], policySlice[1] +} diff --git a/apiserver/pkg/storage/calico/converter.go b/apiserver/pkg/storage/calico/converter.go index dd6eb80a484..138a3aa835d 100644 --- a/apiserver/pkg/storage/calico/converter.go +++ b/apiserver/pkg/storage/calico/converter.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. package calico @@ -32,6 +32,10 @@ func aapiError(err error, key string) error { // This is common code. Refactor this workflow. func convertToAAPI(libcalicoObject runtime.Object) (res runtime.Object) { switch obj := libcalicoObject.(type) { + case *v3.Tier: + aapiTier := &v3.Tier{} + TierConverter{}.convertToAAPI(obj, aapiTier) + return aapiTier case *v3.NetworkPolicy: aapiPolicy := &v3.NetworkPolicy{} NetworkPolicyConverter{}.convertToAAPI(obj, aapiPolicy) diff --git a/apiserver/pkg/storage/calico/globalNetworkPolicy_storage.go b/apiserver/pkg/storage/calico/globalNetworkPolicy_storage.go index 1e720cf3167..93a44902afa 100644 --- a/apiserver/pkg/storage/calico/globalNetworkPolicy_storage.go +++ b/apiserver/pkg/storage/calico/globalNetworkPolicy_storage.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. package calico @@ -90,8 +90,17 @@ func (gc GlobalNetworkPolicyConverter) convertToAAPI(libcalicoObject resourceObj lcgGlobalNetworkPolicy := libcalicoObject.(*api.GlobalNetworkPolicy) aapiGlobalNetworkPolicy := aapiObj.(*aapi.GlobalNetworkPolicy) aapiGlobalNetworkPolicy.Spec = lcgGlobalNetworkPolicy.Spec + // Default the tier field if not specified + if aapiGlobalNetworkPolicy.Spec.Tier == "" { + aapiGlobalNetworkPolicy.Spec.Tier = "default" + } aapiGlobalNetworkPolicy.TypeMeta = lcgGlobalNetworkPolicy.TypeMeta aapiGlobalNetworkPolicy.ObjectMeta = lcgGlobalNetworkPolicy.ObjectMeta + // Workflows associated with label "projectcalico.org/tier" should be deprecated thereafter. + if aapiGlobalNetworkPolicy.Labels == nil { + aapiGlobalNetworkPolicy.Labels = make(map[string]string) + } + aapiGlobalNetworkPolicy.Labels["projectcalico.org/tier"] = aapiGlobalNetworkPolicy.Spec.Tier } func (gc GlobalNetworkPolicyConverter) convertToAAPIList(libcalicoListObject resourceListObject, aapiListObj runtime.Object, pred storage.SelectionPredicate) { diff --git a/apiserver/pkg/storage/calico/gnp_storage_test.go b/apiserver/pkg/storage/calico/gnp_storage_test.go index 2207a83023c..386b6115b60 100644 --- a/apiserver/pkg/storage/calico/gnp_storage_test.go +++ b/apiserver/pkg/storage/calico/gnp_storage_test.go @@ -8,8 +8,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" - v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" ) @@ -18,9 +16,9 @@ func TestInvalidFieldError(t *testing.T) { defer testCleanup(t, ctx, store, gnpStore) key := "projectcalico.org/globalnetworkpolicies/default/default.foo" - out := &calico.GlobalNetworkPolicy{} - obj := &calico.GlobalNetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{Name: "default.foo"}, + out := &v3.GlobalNetworkPolicy{} + obj := &v3.GlobalNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "default.foo$"}, Spec: v3.GlobalNetworkPolicySpec{ Egress: []v3.Rule{{ Action: "Allow", diff --git a/apiserver/pkg/storage/calico/options.go b/apiserver/pkg/storage/calico/options.go index 221ed42cccf..07b520decec 100644 --- a/apiserver/pkg/storage/calico/options.go +++ b/apiserver/pkg/storage/calico/options.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. package calico @@ -8,6 +8,7 @@ import ( const ( PolicyResource string = "policy" + TierResource string = "tier" ) type Options struct { diff --git a/apiserver/pkg/storage/calico/policy_storage.go b/apiserver/pkg/storage/calico/policy_storage.go index 3917535ed59..2ec69705282 100644 --- a/apiserver/pkg/storage/calico/policy_storage.go +++ b/apiserver/pkg/storage/calico/policy_storage.go @@ -1,25 +1,22 @@ -// Copyright (c) 2017-2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. package calico import ( + "context" "reflect" "strings" - "context" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic/registry" k8sStorage "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/storagebackend/factory" - aapi "github.com/projectcalico/api/pkg/apis/projectcalico/v3" - - api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" - "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/clientv3" cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" "github.com/projectcalico/calico/libcalico-go/lib/watch" ) @@ -29,8 +26,8 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory c := CreateClientFromConfig() createFn := func(ctx context.Context, c clientv3.Interface, obj resourceObject, opts clientOpts) (resourceObject, error) { oso := opts.(options.SetOptions) - res := obj.(*api.NetworkPolicy) - if strings.HasPrefix(res.Name, conversion.K8sNetworkPolicyNamePrefix) { + res := obj.(*v3.NetworkPolicy) + if strings.HasPrefix(res.Name, names.K8sNetworkPolicyNamePrefix) { return nil, cerrors.ErrorOperationNotSupported{ Operation: "create or apply", Identifier: obj, @@ -41,8 +38,8 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory } updateFn := func(ctx context.Context, c clientv3.Interface, obj resourceObject, opts clientOpts) (resourceObject, error) { oso := opts.(options.SetOptions) - res := obj.(*api.NetworkPolicy) - if strings.HasPrefix(res.Name, conversion.K8sNetworkPolicyNamePrefix) { + res := obj.(*v3.NetworkPolicy) + if strings.HasPrefix(res.Name, names.K8sNetworkPolicyNamePrefix) { return nil, cerrors.ErrorOperationNotSupported{ Operation: "update or apply", Identifier: obj, @@ -57,7 +54,7 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory } deleteFn := func(ctx context.Context, c clientv3.Interface, ns string, name string, opts clientOpts) (resourceObject, error) { odo := opts.(options.DeleteOptions) - if strings.HasPrefix(name, conversion.K8sNetworkPolicyNamePrefix) { + if strings.HasPrefix(name, names.K8sNetworkPolicyNamePrefix) { return nil, cerrors.ErrorOperationNotSupported{ Operation: "delete", Identifier: name, @@ -74,14 +71,15 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory olo := opts.(options.ListOptions) return c.NetworkPolicies().Watch(ctx, olo) } + // TODO(doublek): Inject codec, client for nicer testing. dryRunnableStorage := registry.DryRunnableStorage{Storage: &resourceStore{ client: c, codec: opts.RESTOptions.StorageConfig.Codec, versioner: APIObjectVersioner{&k8sStorage.APIObjectVersioner{}}, - aapiType: reflect.TypeOf(aapi.NetworkPolicy{}), - aapiListType: reflect.TypeOf(aapi.NetworkPolicyList{}), - libCalicoType: reflect.TypeOf(api.NetworkPolicy{}), - libCalicoListType: reflect.TypeOf(api.NetworkPolicyList{}), + aapiType: reflect.TypeOf(v3.NetworkPolicy{}), + aapiListType: reflect.TypeOf(v3.NetworkPolicyList{}), + libCalicoType: reflect.TypeOf(v3.NetworkPolicy{}), + libCalicoListType: reflect.TypeOf(v3.NetworkPolicyList{}), isNamespaced: true, create: createFn, update: updateFn, @@ -95,39 +93,47 @@ func NewNetworkPolicyStorage(opts Options) (registry.DryRunnableStorage, factory return dryRunnableStorage, func() {} } -type NetworkPolicyConverter struct { -} +type NetworkPolicyConverter struct{} func (rc NetworkPolicyConverter) convertToLibcalico(aapiObj runtime.Object) resourceObject { - aapiPolicy := aapiObj.(*aapi.NetworkPolicy) - lcgPolicy := &api.NetworkPolicy{} + aapiPolicy := aapiObj.(*v3.NetworkPolicy) + lcgPolicy := &v3.NetworkPolicy{} lcgPolicy.TypeMeta = aapiPolicy.TypeMeta lcgPolicy.ObjectMeta = aapiPolicy.ObjectMeta - lcgPolicy.Kind = api.KindNetworkPolicy - lcgPolicy.APIVersion = api.GroupVersionCurrent + lcgPolicy.Kind = v3.KindNetworkPolicy + lcgPolicy.APIVersion = v3.GroupVersionCurrent lcgPolicy.Spec = aapiPolicy.Spec return lcgPolicy } func (rc NetworkPolicyConverter) convertToAAPI(libcalicoObject resourceObject, aapiObj runtime.Object) { - lcgPolicy := libcalicoObject.(*api.NetworkPolicy) - aapiPolicy := aapiObj.(*aapi.NetworkPolicy) + lcgPolicy := libcalicoObject.(*v3.NetworkPolicy) + aapiPolicy := aapiObj.(*v3.NetworkPolicy) aapiPolicy.Spec = lcgPolicy.Spec + // Default the tier field if not specified + if aapiPolicy.Spec.Tier == "" { + aapiPolicy.Spec.Tier = "default" + } aapiPolicy.TypeMeta = lcgPolicy.TypeMeta aapiPolicy.ObjectMeta = lcgPolicy.ObjectMeta + // Workflows associated with label "projectcalico.org/tier" should be deprecated thereafter. + if aapiPolicy.Labels == nil { + aapiPolicy.Labels = make(map[string]string) + } + aapiPolicy.Labels["projectcalico.org/tier"] = aapiPolicy.Spec.Tier } func (rc NetworkPolicyConverter) convertToAAPIList(libcalicoListObject resourceListObject, aapiListObj runtime.Object, pred k8sStorage.SelectionPredicate) { - lcgPolicyList := libcalicoListObject.(*api.NetworkPolicyList) - aapiPolicyList := aapiListObj.(*aapi.NetworkPolicyList) + lcgPolicyList := libcalicoListObject.(*v3.NetworkPolicyList) + aapiPolicyList := aapiListObj.(*v3.NetworkPolicyList) if libcalicoListObject == nil { - aapiPolicyList.Items = []aapi.NetworkPolicy{} + aapiPolicyList.Items = []v3.NetworkPolicy{} return } aapiPolicyList.TypeMeta = lcgPolicyList.TypeMeta aapiPolicyList.ListMeta = lcgPolicyList.ListMeta for _, item := range lcgPolicyList.Items { - aapiPolicy := aapi.NetworkPolicy{} + aapiPolicy := v3.NetworkPolicy{} rc.convertToAAPI(&item, &aapiPolicy) if matched, err := pred.Matches(&aapiPolicy); err == nil && matched { aapiPolicyList.Items = append(aapiPolicyList.Items, aapiPolicy) diff --git a/apiserver/pkg/storage/calico/policy_storage_test.go b/apiserver/pkg/storage/calico/policy_storage_test.go index b82c809388c..90899bfde9f 100644 --- a/apiserver/pkg/storage/calico/policy_storage_test.go +++ b/apiserver/pkg/storage/calico/policy_storage_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. package calico @@ -26,31 +26,33 @@ import ( "context" - calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" "github.com/projectcalico/calico/libcalico-go/lib/clientv3" "github.com/projectcalico/calico/libcalico-go/lib/options" ) -var scheme = runtime.NewScheme() -var codecs = serializer.NewCodecFactory(scheme) +var ( + scheme = runtime.NewScheme() + codecs = serializer.NewCodecFactory(scheme) +) func init() { metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion) - _ = calico.AddToScheme(scheme) + _ = v3.AddToScheme(scheme) } func TestNetworkPolicyCreate(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - key := "projectcalico.org/networkpolicies/default/foo" - out := &calico.NetworkPolicy{} - obj := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}} + key := "projectcalico.org/networkpolicies/default/default.foo" + out := &v3.NetworkPolicy{} + obj := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.foo"}} // verify that kv pair is empty before set - libcPolicy, _ := store.client.NetworkPolicies().Get(ctx, "default", "foo", options.GetOptions{}) + libcPolicy, _ := store.client.NetworkPolicies().Get(ctx, "default", "default.foo", options.GetOptions{}) if libcPolicy != nil { t.Fatalf("expecting empty result on key: %s", key) } @@ -68,7 +70,7 @@ func TestNetworkPolicyCreate(t *testing.T) { } // verify that kv pair is not empty after set - libcPolicy, err = store.client.NetworkPolicies().Get(ctx, "default", "foo", options.GetOptions{}) + libcPolicy, err = store.client.NetworkPolicies().Get(ctx, "default", "default.foo", options.GetOptions{}) if err != nil { t.Fatalf("libcalico networkpolicy client get failed: %v", err) } @@ -81,10 +83,10 @@ func TestNetworkPolicyCreateWithTTL(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - input := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}} - key := "projectcalico.org/networkpolicies/default/foo" + input := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.foo"}} + key := "projectcalico.org/networkpolicies/default/default.foo" - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} if err := store.Create(ctx, key, input, out, 1); err != nil { t.Fatalf("Create failed: %v", err) } @@ -100,9 +102,9 @@ func TestNetworkPolicyCreateWithKeyExist(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - obj := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}} + obj := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.foo"}} key, _ := testPropagateStore(ctx, t, store, obj) - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} err := store.Create(ctx, key, obj, out, 0) if err == nil || !storage.IsExist(err) { t.Errorf("expecting key exists error, but get: %s", err) @@ -116,8 +118,8 @@ func TestNetworkPolicyCreateDisallowK8sPrefix(t *testing.T) { ns := "default" key := fmt.Sprintf("projectcalico.org/networkpolicies/%s/%s", ns, name) - out := &calico.NetworkPolicy{} - obj := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: name}} + out := &v3.NetworkPolicy{} + obj := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: name}} libcPolicy, _ := store.client.NetworkPolicies().Get(ctx, ns, name, options.GetOptions{}) if libcPolicy != nil { @@ -134,13 +136,13 @@ func TestNetworkPolicyGet(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - key, storedObj := testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) + key, storedObj := testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) tests := []struct { key string ignoreNotFound bool expectNotFoundErr bool - expectedOut *calico.NetworkPolicy + expectedOut *v3.NetworkPolicy }{{ // test get on existing item key: key, ignoreNotFound: false, @@ -154,11 +156,11 @@ func TestNetworkPolicyGet(t *testing.T) { key: "projectcalico.org/networkpolicies/default/non-existing", ignoreNotFound: true, expectNotFoundErr: false, - expectedOut: &calico.NetworkPolicy{}, + expectedOut: &v3.NetworkPolicy{}, }} for i, tt := range tests { - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} opts := storage.GetOptions{IgnoreNotFound: tt.ignoreNotFound} err := store.Get(ctx, tt.key, opts, out) if tt.expectNotFoundErr { @@ -180,11 +182,11 @@ func TestNetworkPolicyUnconditionalDelete(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - key, storedObj := testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) + key, storedObj := testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) tests := []struct { key string - expectedObj *calico.NetworkPolicy + expectedObj *v3.NetworkPolicy expectNotFoundErr bool }{{ // test unconditional delete on existing key key: key, @@ -197,7 +199,7 @@ func TestNetworkPolicyUnconditionalDelete(t *testing.T) { }} for i, tt := range tests { - out := &calico.NetworkPolicy{} // reset + out := &v3.NetworkPolicy{} // reset err := store.Delete(ctx, tt.key, out, nil, nil, nil) if tt.expectNotFoundErr { if err == nil || !storage.IsNotFound(err) { @@ -218,7 +220,7 @@ func TestNetworkPolicyConditionalDelete(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - key, storedObj := testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo", UID: "A"}}) + key, storedObj := testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo", UID: "A"}}) tests := []struct { precondition *storage.Preconditions @@ -232,7 +234,7 @@ func TestNetworkPolicyConditionalDelete(t *testing.T) { }} for i, tt := range tests { - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} err := store.Delete(ctx, key, out, tt.precondition, nil, nil) if tt.expectInvalidObjErr { if err == nil || !storage.IsInvalidObj(err) { @@ -246,7 +248,7 @@ func TestNetworkPolicyConditionalDelete(t *testing.T) { if !reflect.DeepEqual(storedObj, out) { t.Errorf("#%d: pod want=%#v, get=%#v", i, storedObj, out) } - key, storedObj = testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo", UID: "A"}}) + key, storedObj = testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo", UID: "A"}}) } } @@ -257,7 +259,7 @@ func TestNetworkPolicyDeleteDisallowK8sPrefix(t *testing.T) { ns := "default" key := fmt.Sprintf("projectcalico.org/networkpolicies/%s/%s", ns, name) - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} err := store.Delete(ctx, key, out, nil, nil, nil) if err == nil { t.Fatalf("Expected deleting a k8s network policy to error") @@ -268,17 +270,17 @@ func TestNetworkPolicyGetList(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - key, storedObj := testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) + key, storedObj := testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) tests := []struct { key string pred storage.SelectionPredicate - expectedOut []*calico.NetworkPolicy - }{{ // test GetList on existing key + expectedOut []*v3.NetworkPolicy + }{{ // test GetToList on existing key key: key, pred: storage.Everything, - expectedOut: []*calico.NetworkPolicy{storedObj}, - }, { // test GetList on non-existing key + expectedOut: []*v3.NetworkPolicy{storedObj}, + }, { // test GetToList on non-existing key key: "projectcalico.org/networkpolicies/default/non-existing", pred: storage.Everything, expectedOut: nil, @@ -288,7 +290,7 @@ func TestNetworkPolicyGetList(t *testing.T) { Label: labels.Everything(), Field: fields.ParseSelectorOrDie("metadata.name!=" + storedObj.Name), GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - policy := obj.(*calico.NetworkPolicy) + policy := obj.(*v3.NetworkPolicy) return nil, fields.Set{"metadata.name": policy.Name}, nil }, }, @@ -296,7 +298,7 @@ func TestNetworkPolicyGetList(t *testing.T) { }} for i, tt := range tests { - out := &calico.NetworkPolicyList{} + out := &v3.NetworkPolicyList{} opts := storage.ListOptions{Predicate: tt.pred} err := store.GetList(ctx, tt.key, opts, out) if err != nil { @@ -319,9 +321,9 @@ func TestNetworkPolicyGuaranteedUpdate(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer func() { testCleanup(t, ctx, store, gnpStore) - _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "non-existing", options.DeleteOptions{}) + _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "default.non-existing", options.DeleteOptions{}) }() - key, storeObj := testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo", UID: "A"}}) + key, storeObj := testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo", UID: "A"}}) tests := []struct { key string @@ -332,7 +334,7 @@ func TestNetworkPolicyGuaranteedUpdate(t *testing.T) { expectNoUpdate bool transformStale bool }{{ // GuaranteedUpdate on non-existing key with ignoreNotFound=false - key: "projectcalico.org/networkpolicies/default/non-existing", + key: "projectcalico.org/networkpolicies/default/default.non-existing", ignoreNotFound: false, precondition: nil, expectNotFoundErr: true, @@ -340,7 +342,7 @@ func TestNetworkPolicyGuaranteedUpdate(t *testing.T) { expectNoUpdate: false, }, { // GuaranteedUpdate on non-existing key with ignoreNotFound=true // This would update datastore revision. - key: "projectcalico.org/networkpolicies/default/non-existing", + key: "projectcalico.org/networkpolicies/default/default.non-existing", ignoreNotFound: true, precondition: nil, expectNotFoundErr: false, @@ -386,7 +388,7 @@ func TestNetworkPolicyGuaranteedUpdate(t *testing.T) { for i, tt := range tests { klog.Infof("Start to run test on tt: %+v", tt) - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} selector := fmt.Sprintf("my_label == \"foo-%d\"", i) if tt.expectNoUpdate { selector = "" @@ -399,7 +401,7 @@ func TestNetworkPolicyGuaranteedUpdate(t *testing.T) { err = store.GuaranteedUpdate(ctx, tt.key, out, tt.ignoreNotFound, tt.precondition, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { if tt.expectNotFoundErr && tt.ignoreNotFound { - if policy := obj.(*calico.NetworkPolicy); policy.Spec.Selector != "" { + if policy := obj.(*v3.NetworkPolicy); policy.Spec.Selector != "" { t.Errorf("#%d: expecting zero value, but get=%#v", i, policy) } } @@ -407,7 +409,7 @@ func TestNetworkPolicyGuaranteedUpdate(t *testing.T) { policy := *storeObj // Set correct resource name, don't update "non-existing" to "foo" if strings.Contains(tt.key, "non-existing") { - policy.Name = "non-existing" + policy.Name = "default.non-existing" // Clean resource version for non-existing object policy.GetObjectMeta().SetResourceVersion("") @@ -462,12 +464,12 @@ func TestNetworkPolicyGuaranteedUpdateWithTTL(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - input := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}} + input := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.foo"}} input.SetCreationTimestamp(metav1.Time{Time: time.Now()}) input.SetUID("test_uid") - key := "projectcalico.org/networkpolicies/default/foo" + key := "projectcalico.org/networkpolicies/default/default.foo" - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} err := store.GuaranteedUpdate(ctx, key, out, true, nil, func(_ runtime.Object, _ storage.ResponseMeta) (runtime.Object, *uint64, error) { ttl := uint64(1) @@ -488,7 +490,7 @@ func TestNetworkPolicyGuaranteedUpdateWithTTL(t *testing.T) { func TestNetworkPolicyGuaranteedUpdateWithConflict(t *testing.T) { ctx, store, gnpStore := testSetup(t) defer testCleanup(t, ctx, store, gnpStore) - key, _ := testPropagateStore(ctx, t, store, &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}) + key, _ := testPropagateStore(ctx, t, store, &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.foo"}}) errChan := make(chan error, 1) var firstToFinish sync.WaitGroup @@ -497,9 +499,9 @@ func TestNetworkPolicyGuaranteedUpdateWithConflict(t *testing.T) { secondToEnter.Add(1) go func() { - err := store.GuaranteedUpdate(ctx, key, &calico.NetworkPolicy{}, false, nil, + err := store.GuaranteedUpdate(ctx, key, &v3.NetworkPolicy{}, false, nil, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { - policy := obj.(*calico.NetworkPolicy) + policy := obj.(*v3.NetworkPolicy) policy.Spec.Selector = "my_label == \"foo-1\"" secondToEnter.Wait() return policy, nil @@ -509,14 +511,14 @@ func TestNetworkPolicyGuaranteedUpdateWithConflict(t *testing.T) { }() updateCount := 0 - err := store.GuaranteedUpdate(ctx, key, &calico.NetworkPolicy{}, false, nil, + err := store.GuaranteedUpdate(ctx, key, &v3.NetworkPolicy{}, false, nil, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { if updateCount == 0 { secondToEnter.Done() firstToFinish.Wait() } updateCount++ - policy := obj.(*calico.NetworkPolicy) + policy := obj.(*v3.NetworkPolicy) policy.Spec.Selector = "my_label == \"foo-2\"" return policy, nil }), nil) @@ -542,21 +544,21 @@ func TestNetworkPolicyList(t *testing.T) { preset := []struct { key string - obj *calico.NetworkPolicy - storedObj *calico.NetworkPolicy + obj *v3.NetworkPolicy + storedObj *v3.NetworkPolicy }{{ key: "projectcalico.org/networkpolicies/default/foo", - obj: &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}, + obj: &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}}, }, { key: "projectcalico.org/networkpolicies/default1/foo", - obj: &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default1", Name: "foo"}}, + obj: &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default1", Name: "foo"}}, }, { key: "projectcalico.org/networkpolicies/default1/bar", - obj: &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default1", Name: "bar"}}, + obj: &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default1", Name: "bar"}}, }} for i, ps := range preset { - preset[i].storedObj = &calico.NetworkPolicy{} + preset[i].storedObj = &v3.NetworkPolicy{} err := store.Create(ctx, ps.key, ps.obj, preset[i].storedObj, 0) if err != nil { t.Fatalf("Set failed: %v", err) @@ -566,11 +568,11 @@ func TestNetworkPolicyList(t *testing.T) { tests := []struct { prefix string pred storage.SelectionPredicate - expectedOut []*calico.NetworkPolicy + expectedOut []*v3.NetworkPolicy }{{ // test List on existing key prefix: "projectcalico.org/networkpolicies/default/", pred: storage.Everything, - expectedOut: []*calico.NetworkPolicy{preset[0].storedObj}, + expectedOut: []*v3.NetworkPolicy{preset[0].storedObj}, }, { // test List on non-existing key prefix: "projectcalico.org/networkpolicies/non-existing/", pred: storage.Everything, @@ -581,7 +583,7 @@ func TestNetworkPolicyList(t *testing.T) { Label: labels.Everything(), Field: fields.ParseSelectorOrDie("metadata.name!=" + preset[0].storedObj.Name), GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - policy := obj.(*calico.NetworkPolicy) + policy := obj.(*v3.NetworkPolicy) return nil, fields.Set{"metadata.name": policy.Name}, nil }, }, @@ -589,11 +591,11 @@ func TestNetworkPolicyList(t *testing.T) { }, { // test List with multiple levels of directories and expect flattened result prefix: "projectcalico.org/networkpolicies/", pred: storage.Everything, - expectedOut: []*calico.NetworkPolicy{preset[0].storedObj, preset[2].storedObj, preset[1].storedObj}, + expectedOut: []*v3.NetworkPolicy{preset[0].storedObj, preset[2].storedObj, preset[1].storedObj}, }} for i, tt := range tests { - out := &calico.NetworkPolicyList{} + out := &v3.NetworkPolicyList{} opts := storage.ListOptions{ResourceVersion: "0", Predicate: tt.pred} err := store.List(ctx, tt.prefix, opts, out) if err != nil { @@ -613,7 +615,7 @@ func TestNetworkPolicyList(t *testing.T) { } func testSetup(t *testing.T) (context.Context, *resourceStore, *resourceStore) { - codec := apitesting.TestCodec(codecs, calico.SchemeGroupVersion) + codec := apitesting.TestCodec(codecs, v3.SchemeGroupVersion) cfg, err := apiconfig.LoadClientConfig("") if err != nil { klog.Errorf("Failed to load client config: %q", err) @@ -645,22 +647,22 @@ func testSetup(t *testing.T) (context.Context, *resourceStore, *resourceStore) { } func testCleanup(t *testing.T, ctx context.Context, store, gnpStore *resourceStore) { - np, _ := store.client.NetworkPolicies().Get(ctx, "default", "foo", options.GetOptions{}) + np, _ := store.client.NetworkPolicies().Get(ctx, "default", "default.foo", options.GetOptions{}) if np != nil { - _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "foo", options.DeleteOptions{}) + _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "default.foo", options.DeleteOptions{}) } - gnp, _ := gnpStore.client.GlobalNetworkPolicies().Get(ctx, "foo", options.GetOptions{}) + gnp, _ := gnpStore.client.GlobalNetworkPolicies().Get(ctx, "default.foo", options.GetOptions{}) if gnp != nil { - _, _ = gnpStore.client.GlobalNetworkPolicies().Delete(ctx, "foo", options.DeleteOptions{}) + _, _ = gnpStore.client.GlobalNetworkPolicies().Delete(ctx, "default.foo", options.DeleteOptions{}) } } // testPropagateStore helps propagates store with objects, automates key generation, and returns // keys and stored objects. -func testPropagateStore(ctx context.Context, t *testing.T, store *resourceStore, obj *calico.NetworkPolicy) (string, *calico.NetworkPolicy) { +func testPropagateStore(ctx context.Context, t *testing.T, store *resourceStore, obj *v3.NetworkPolicy) (string, *v3.NetworkPolicy) { // Setup store with a key and grab the output for returning. - key := "projectcalico.org/networkpolicies/default/foo" - setOutput := &calico.NetworkPolicy{} + key := "projectcalico.org/networkpolicies/default/default.foo" + setOutput := &v3.NetworkPolicy{} err := store.Create(ctx, key, obj, setOutput, 0) if err != nil { t.Fatalf("Set failed: %v", err) diff --git a/apiserver/pkg/storage/calico/resource.go b/apiserver/pkg/storage/calico/resource.go index 82a03c0dbe9..bb0c3d832b4 100644 --- a/apiserver/pkg/storage/calico/resource.go +++ b/apiserver/pkg/storage/calico/resource.go @@ -4,14 +4,13 @@ package calico import ( "bytes" + "context" "fmt" "os" "reflect" "strconv" "time" - "context" - aapierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -91,6 +90,11 @@ func CreateClientFromConfig() clientv3.Interface { os.Exit(1) } + // if QPS not set in config, set default QPS + if cfg.Spec.K8sClientQPS == float32(0) { + cfg.Spec.K8sClientQPS = 50 + } + c, err := clientv3.New(*cfg) if err != nil { klog.Errorf("Failed creating client: %q", err) diff --git a/apiserver/pkg/storage/calico/storage_interface.go b/apiserver/pkg/storage/calico/storage_interface.go index 800be37cdf0..d8cca01b5d1 100644 --- a/apiserver/pkg/storage/calico/storage_interface.go +++ b/apiserver/pkg/storage/calico/storage_interface.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. package calico @@ -17,6 +17,8 @@ func NewStorage(opts Options) (registry.DryRunnableStorage, factory.DestroyFunc) return NewNetworkPolicyStorage(opts) case "projectcalico.org/globalnetworkpolicies": return NewGlobalNetworkPolicyStorage(opts) + case "projectcalico.org/tiers": + return NewTierStorage(opts) case "projectcalico.org/globalnetworksets": return NewGlobalNetworkSetStorage(opts) case "projectcalico.org/networksets": diff --git a/apiserver/pkg/storage/calico/tier_storage.go b/apiserver/pkg/storage/calico/tier_storage.go new file mode 100644 index 00000000000..ec01a8375e5 --- /dev/null +++ b/apiserver/pkg/storage/calico/tier_storage.go @@ -0,0 +1,112 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package calico + +import ( + "reflect" + + "golang.org/x/net/context" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/storagebackend/factory" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/options" + "github.com/projectcalico/calico/libcalico-go/lib/watch" +) + +// NewTierStorage creates a new libcalico-based storage.Interface implementation for Tiers +func NewTierStorage(opts Options) (registry.DryRunnableStorage, factory.DestroyFunc) { + c := CreateClientFromConfig() + createFn := func(ctx context.Context, c clientv3.Interface, obj resourceObject, opts clientOpts) (resourceObject, error) { + oso := opts.(options.SetOptions) + res := obj.(*v3.Tier) + return c.Tiers().Create(ctx, res, oso) + } + updateFn := func(ctx context.Context, c clientv3.Interface, obj resourceObject, opts clientOpts) (resourceObject, error) { + oso := opts.(options.SetOptions) + res := obj.(*v3.Tier) + return c.Tiers().Update(ctx, res, oso) + } + getFn := func(ctx context.Context, c clientv3.Interface, ns string, name string, opts clientOpts) (resourceObject, error) { + ogo := opts.(options.GetOptions) + return c.Tiers().Get(ctx, name, ogo) + } + deleteFn := func(ctx context.Context, c clientv3.Interface, ns string, name string, opts clientOpts) (resourceObject, error) { + odo := opts.(options.DeleteOptions) + return c.Tiers().Delete(ctx, name, odo) + } + listFn := func(ctx context.Context, c clientv3.Interface, opts clientOpts) (resourceListObject, error) { + olo := opts.(options.ListOptions) + return c.Tiers().List(ctx, olo) + } + watchFn := func(ctx context.Context, c clientv3.Interface, opts clientOpts) (watch.Interface, error) { + olo := opts.(options.ListOptions) + return c.Tiers().Watch(ctx, olo) + } + + // TODO(doublek): Inject codec, client for nicer testing. + dryRunnableStorage := registry.DryRunnableStorage{Storage: &resourceStore{ + client: c, + codec: opts.RESTOptions.StorageConfig.Codec, + versioner: APIObjectVersioner{}, + aapiType: reflect.TypeOf(v3.Tier{}), + aapiListType: reflect.TypeOf(v3.TierList{}), + libCalicoType: reflect.TypeOf(v3.Tier{}), + libCalicoListType: reflect.TypeOf(v3.TierList{}), + isNamespaced: false, + create: createFn, + update: updateFn, + get: getFn, + delete: deleteFn, + list: listFn, + watch: watchFn, + resourceName: "Tier", + converter: TierConverter{}, + }, Codec: opts.RESTOptions.StorageConfig.Codec} + return dryRunnableStorage, func() {} +} + +type TierConverter struct { +} + +func (tc TierConverter) convertToLibcalico(aapiObj runtime.Object) resourceObject { + aapiTier := aapiObj.(*v3.Tier) + lcgTier := &v3.Tier{} + lcgTier.TypeMeta = aapiTier.TypeMeta + lcgTier.ObjectMeta = aapiTier.ObjectMeta + lcgTier.Kind = v3.KindTier + lcgTier.APIVersion = v3.GroupVersionCurrent + lcgTier.Spec = aapiTier.Spec + return lcgTier +} + +func (tc TierConverter) convertToAAPI(libcalicoObject resourceObject, aapiObj runtime.Object) { + lcgTier := libcalicoObject.(*v3.Tier) + aapiTier := aapiObj.(*v3.Tier) + aapiTier.Spec = lcgTier.Spec + aapiTier.TypeMeta = lcgTier.TypeMeta + aapiTier.ObjectMeta = lcgTier.ObjectMeta +} + +func (tc TierConverter) convertToAAPIList(libcalicoListObject resourceListObject, aapiListObj runtime.Object, pred storage.SelectionPredicate) { + lcgTierList := libcalicoListObject.(*v3.TierList) + aapiTierList := aapiListObj.(*v3.TierList) + if libcalicoListObject == nil { + aapiTierList.Items = []v3.Tier{} + return + } + aapiTierList.TypeMeta = lcgTierList.TypeMeta + aapiTierList.ListMeta = lcgTierList.ListMeta + for _, item := range lcgTierList.Items { + aapiTier := v3.Tier{} + tc.convertToAAPI(&item, &aapiTier) + if matched, err := pred.Matches(&aapiTier); err == nil && matched { + aapiTierList.Items = append(aapiTierList.Items, aapiTier) + } + } +} diff --git a/apiserver/pkg/storage/calico/tier_storage_test.go b/apiserver/pkg/storage/calico/tier_storage_test.go new file mode 100644 index 00000000000..5e9a0af83f8 --- /dev/null +++ b/apiserver/pkg/storage/calico/tier_storage_test.go @@ -0,0 +1,650 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package calico + +import ( + "fmt" + "os" + "reflect" + "strconv" + "strings" + "sync" + "testing" + "time" + + apitesting "k8s.io/apimachinery/pkg/api/apitesting" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/registry/generic" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/storagebackend" + "k8s.io/klog/v2" + + "golang.org/x/net/context" + + "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" + "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/names" + "github.com/projectcalico/calico/libcalico-go/lib/options" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" +) + +func init() { + metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion) + _ = v3.AddToScheme(scheme) +} + +func TestTierCreate(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + key := "projectcalico.org/tiers/foo" + out := &v3.Tier{} + obj := makeTierWithDefaults() + + // verify that kv pair is empty before set + libcTier, _ := store.client.Tiers().Get(ctx, "foo", options.GetOptions{}) + if libcTier != nil { + t.Fatalf("expecting empty result on key: %s", key) + } + + err := store.Create(ctx, key, obj, out, 0) + if err != nil { + t.Fatalf("Set failed: %v", err) + } + // basic tests of the output + if obj.ObjectMeta.Name != out.ObjectMeta.Name { + t.Errorf("pod name want=%s, get=%s", obj.ObjectMeta.Name, out.ObjectMeta.Name) + } + if out.ResourceVersion == "" { + t.Errorf("output should have non-empty resource version") + } + + // verify that kv pair is not empty after set + libcTier, err = store.client.Tiers().Get(ctx, "foo", options.GetOptions{}) + if err != nil { + t.Fatalf("libcalico Tier client get failed: %v", err) + } + if libcTier == nil { + t.Fatalf("expecting empty result on key: %s", key) + } +} + +func TestTierCreateWithTTL(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + input := makeTierWithDefaults() + key := "projectcalico.org/tiers/foo" + + out := &v3.Tier{} + if err := store.Create(ctx, key, input, out, 1); err != nil { + t.Fatalf("Create failed: %v", err) + } + + opts := storage.ListOptions{ResourceVersion: out.ResourceVersion, Predicate: storage.Everything} + w, err := store.Watch(ctx, key, opts) + if err != nil { + t.Fatalf("Watch failed: %v", err) + } + testCheckEventType(t, watch.Deleted, w) +} + +func TestTierCreateWithKeyExist(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + obj := makeTierWithDefaults() + key, _ := testTierPropogateStore(ctx, t, store, obj) + out := &v3.Tier{} + err := store.Create(ctx, key, obj, out, 0) + if err == nil || !storage.IsExist(err) { + t.Errorf("expecting key exists error, but get: %s", err) + } +} + +func TestTierGet(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + key, storedObj := testTierPropogateStore(ctx, t, store, makeTierWithDefaults()) + + tests := []struct { + key string + ignoreNotFound bool + expectNotFoundErr bool + expectedOut *v3.Tier + }{{ // test get on existing item + key: key, + ignoreNotFound: false, + expectNotFoundErr: false, + expectedOut: storedObj, + }, { // test get on non-existing item with ignoreNotFound=false + key: "projectcalico.org/tiers/non-existing", + ignoreNotFound: false, + expectNotFoundErr: true, + }, { // test get on non-existing item with ignoreNotFound=true + key: "projectcalico.org/tiers/non-existing", + ignoreNotFound: true, + expectNotFoundErr: false, + expectedOut: &v3.Tier{}, + }} + + for i, tt := range tests { + out := &v3.Tier{} + opts := storage.GetOptions{IgnoreNotFound: tt.ignoreNotFound} + err := store.Get(ctx, tt.key, opts, out) + if tt.expectNotFoundErr { + if err == nil || !storage.IsNotFound(err) { + t.Errorf("#%d: expecting not found error, but get: %s", i, err) + } + continue + } + if err != nil { + t.Fatalf("Get failed: %v", err) + } + if !reflect.DeepEqual(tt.expectedOut, out) { + t.Errorf("#%d: pod want=%#v, get=%#v", i, tt.expectedOut, out) + } + } +} + +func TestTierUnconditionalDelete(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + key, storedObj := testTierPropogateStore(ctx, t, store, makeTierWithDefaults()) + + tests := []struct { + key string + expectedObj *v3.Tier + expectNotFoundErr bool + }{{ // test unconditional delete on existing key + key: key, + expectedObj: storedObj, + expectNotFoundErr: false, + }, { // test unconditional delete on non-existing key + key: "projectcalico.org/tiers/non-existing", + expectedObj: nil, + expectNotFoundErr: true, + }} + + for i, tt := range tests { + out := &v3.Tier{} // reset + err := store.Delete(ctx, tt.key, out, nil, nil, nil) + if tt.expectNotFoundErr { + if err == nil || !storage.IsNotFound(err) { + t.Errorf("#%d: expecting not found error, but get: %s", i, err) + } + continue + } + if err != nil { + t.Fatalf("Delete failed: %v", err) + } + if !reflect.DeepEqual(tt.expectedObj, out) { + t.Errorf("#%d: pod want=%#v, get=%#v", i, tt.expectedObj, out) + } + } +} + +func TestTierConditionalDelete(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + key, storedObj := testTierPropogateStore(ctx, t, store, makeTier("foo", "A", 10.0)) + + tests := []struct { + precondition *storage.Preconditions + expectInvalidObjErr bool + }{{ // test conditional delete with UID match + precondition: storage.NewUIDPreconditions("A"), + expectInvalidObjErr: false, + }, { // test conditional delete with UID mismatch + precondition: storage.NewUIDPreconditions("B"), + expectInvalidObjErr: true, + }} + + for i, tt := range tests { + out := &v3.Tier{} + err := store.Delete(ctx, key, out, tt.precondition, nil, nil) + if tt.expectInvalidObjErr { + if err == nil || !storage.IsInvalidObj(err) { + t.Errorf("#%d: expecting invalid UID error, but get: %s", i, err) + } + continue + } + if err != nil { + t.Fatalf("Delete failed: %v", err) + } + if !reflect.DeepEqual(storedObj, out) { + t.Errorf("#%d: pod want=%#v, get=%#v", i, storedObj, out) + } + key, storedObj = testTierPropogateStore(ctx, t, store, makeTier("foo", "A", 10.0)) + } +} + +func TestTierGetList(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + key, storedObj := testTierPropogateStore(ctx, t, store, makeTierWithDefaults()) + + tests := []struct { + key string + pred storage.SelectionPredicate + expectedOut []*v3.Tier + }{{ // test GetList on existing key + key: key, + pred: storage.Everything, + expectedOut: []*v3.Tier{storedObj}, + }, { // test GetList on non-existing key + key: "projectcalico.org/tiers/non-existing", + pred: storage.Everything, + expectedOut: nil, + }, { // test GetList with matching tier name + key: "projectcalico.org/tiers/non-existing", + pred: storage.SelectionPredicate{ + Label: labels.Everything(), + Field: fields.ParseSelectorOrDie("metadata.name!=" + storedObj.Name), + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + tier := obj.(*v3.Tier) + return nil, fields.Set{"metadata.name": tier.Name}, nil + }, + }, + expectedOut: nil, + }} + + for i, tt := range tests { + out := &v3.TierList{} + opts := storage.ListOptions{Predicate: tt.pred} + err := store.GetList(ctx, tt.key, opts, out) + if err != nil { + t.Fatalf("GetList failed: %v", err) + } + if len(out.Items) != len(tt.expectedOut) { + t.Errorf("#%d: length of list want=%d, get=%d", i, len(tt.expectedOut), len(out.Items)) + continue + } + for j, wantTier := range tt.expectedOut { + getTier := &out.Items[j] + if !reflect.DeepEqual(wantTier, getTier) { + t.Errorf("#%d: pod want=%#v, get=%#v", i, wantTier, getTier) + } + } + } +} + +func TestTierGuaranteedUpdate(t *testing.T) { + ctx, store := testTierSetup(t) + defer func() { + testTierCleanup(t, ctx, store) + _, _ = store.client.Tiers().Delete(ctx, "non-existing", options.DeleteOptions{}) + }() + key, storeObj := testTierPropogateStore(ctx, t, store, makeTier("foo", "A", 10.0)) + + tests := []struct { + key string + ignoreNotFound bool + precondition *storage.Preconditions + expectNotFoundErr bool + expectInvalidObjErr bool + expectNoUpdate bool + transformStale bool + }{{ // GuaranteedUpdate on non-existing key with ignoreNotFound=false + key: "projectcalico.org/tiers/non-existing", + ignoreNotFound: false, + precondition: nil, + expectNotFoundErr: true, + expectInvalidObjErr: false, + expectNoUpdate: false, + }, { // GuaranteedUpdate on non-existing key with ignoreNotFound=true + // This would update datastore revision. + key: "projectcalico.org/tiers/non-existing", + ignoreNotFound: true, + precondition: nil, + expectNotFoundErr: false, + expectInvalidObjErr: false, + expectNoUpdate: false, + }, { // GuaranteedUpdate on existing key + key: key, + ignoreNotFound: false, + precondition: nil, + expectNotFoundErr: false, + expectInvalidObjErr: false, + expectNoUpdate: false, + }, { // GuaranteedUpdate with same data + key: key, + ignoreNotFound: false, + precondition: nil, + expectNotFoundErr: false, + expectInvalidObjErr: false, + expectNoUpdate: true, + }, { // GuaranteedUpdate with same data but stale + key: key, + ignoreNotFound: false, + precondition: nil, + expectNotFoundErr: false, + expectInvalidObjErr: false, + expectNoUpdate: false, + transformStale: true, + }, { // GuaranteedUpdate with UID match + key: key, + ignoreNotFound: false, + precondition: storage.NewUIDPreconditions("A"), + expectNotFoundErr: false, + expectInvalidObjErr: false, + expectNoUpdate: true, + }, { // GuaranteedUpdate with UID mismatch + key: key, + ignoreNotFound: false, + precondition: storage.NewUIDPreconditions("B"), + expectNotFoundErr: false, + expectInvalidObjErr: true, + expectNoUpdate: true, + }} + + for i, tt := range tests { + klog.Infof("Start to run test on tt: %+v", tt) + out := &v3.Tier{} + selector := fmt.Sprintf("foo-%d", i) + if tt.expectNoUpdate { + selector = "" + } + version := storeObj.ResourceVersion + versionInt, err := strconv.Atoi(version) + if err != nil { + t.Errorf("#%d: failed to convert original version %s to int", i, version) + } + err = store.GuaranteedUpdate(ctx, tt.key, out, tt.ignoreNotFound, tt.precondition, + storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { + if tt.expectNotFoundErr && tt.ignoreNotFound { + if tier := obj.(*v3.Tier); tier.GenerateName != "" { + t.Errorf("#%d: expecting zero value, but get=%#v", i, tier) + } + } + tier := *storeObj + // Set correct resource name, don't update "non-existing" to "foo" + if strings.Contains(tt.key, "non-existing") { + tier.Name = "non-existing" + // Clean resource version for non-existing object + tier.GetObjectMeta().SetResourceVersion("") + + } + if !tt.expectNoUpdate { + tier.GenerateName = selector + } + return &tier, nil + }), nil) + + if tt.expectNotFoundErr { + if err == nil || !storage.IsNotFound(err) { + t.Errorf("#%d: expecting not found error, but get: %v", i, err) + } + continue + } + if tt.expectInvalidObjErr { + if err == nil || !storage.IsInvalidObj(err) { + t.Errorf("#%d: expecting invalid UID error, but get: %s", i, err) + } + continue + } + if err != nil { + t.Fatalf("GuaranteedUpdate failed: %v", err) + } + if !tt.expectNoUpdate { + if out.GenerateName != selector { + t.Errorf("#%d: tier selector want=%s, get=%s", i, selector, out.GenerateName) + } + } + switch tt.expectNoUpdate { + case true: + outInt, err := strconv.Atoi(out.ResourceVersion) + if err != nil { + t.Errorf("#%d: failed to convert out resource version %s to int", i, out.ResourceVersion) + } + // After creation of a "non-existing" object by previous test, the resource version has increased by 1 for + // new updates. + if outInt != (versionInt + 1) { + t.Errorf("#%d: expect no version change, before=%s, after=%s", i, version, out.ResourceVersion) + } + case false: + if version == out.ResourceVersion { + t.Errorf("#%d: expect version change, but get the same version=%s", i, version) + } + } + storeObj = out + } +} + +func TestTierGuaranteedUpdateWithTTL(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + + input := makeTierWithDefaults() + input.SetCreationTimestamp(metav1.Time{Time: time.Now()}) + input.SetUID("test_uid") + key := "projectcalico.org/tiers/foo" + + out := &v3.Tier{} + err := store.GuaranteedUpdate(ctx, key, out, true, nil, + func(_ runtime.Object, _ storage.ResponseMeta) (runtime.Object, *uint64, error) { + ttl := uint64(1) + return input, &ttl, nil + }, nil) + if err != nil { + t.Fatalf("Create failed: %v", err) + } + + opts := storage.ListOptions{ResourceVersion: out.ResourceVersion, Predicate: storage.Everything} + w, err := store.Watch(ctx, key, opts) + if err != nil { + t.Fatalf("Watch failed: %v", err) + } + testCheckEventType(t, watch.Deleted, w) +} + +func TestTierGuaranteedUpdateWithConflict(t *testing.T) { + ctx, store := testTierSetup(t) + defer testTierCleanup(t, ctx, store) + key, _ := testTierPropogateStore(ctx, t, store, makeTierWithDefaults()) + + errChan := make(chan error, 1) + var firstToFinish sync.WaitGroup + var secondToEnter sync.WaitGroup + firstToFinish.Add(1) + secondToEnter.Add(1) + + go func() { + err := store.GuaranteedUpdate(ctx, key, &v3.Tier{}, false, nil, + storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { + tier := obj.(*v3.Tier) + tier.GenerateName = "foo-1" + secondToEnter.Wait() + return tier, nil + }), nil) + firstToFinish.Done() + errChan <- err + }() + + updateCount := 0 + err := store.GuaranteedUpdate(ctx, key, &v3.Tier{}, false, nil, + storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { + if updateCount == 0 { + secondToEnter.Done() + firstToFinish.Wait() + } + updateCount++ + tier := obj.(*v3.Tier) + tier.GenerateName = "foo-2" + return tier, nil + }), nil) + if err != nil { + t.Fatalf("Second GuaranteedUpdate error %#v", err) + } + if err := <-errChan; err != nil { + t.Fatalf("First GuaranteedUpdate error %#v", err) + } + + if updateCount != 2 { + t.Errorf("Should have conflict and called update func twice") + } +} + +func TestTierList(t *testing.T) { + ctx, store := testTierSetup(t) + defer func() { + _, _ = store.client.Tiers().Delete(ctx, "foo", options.DeleteOptions{}) + _, _ = store.client.Tiers().Delete(ctx, "bar", options.DeleteOptions{}) + }() + + preset := []struct { + key string + obj *v3.Tier + storedObj *v3.Tier + }{{ + key: "projectcalico.org/tiers/foo", + obj: makeTierWithDefaults(), + }, { + key: "projectcalico.org/tiers/bar", + obj: makeTier("bar", "", 20.0), + }} + + for i, ps := range preset { + preset[i].storedObj = &v3.Tier{} + err := store.Create(ctx, ps.key, ps.obj, preset[i].storedObj, 0) + if err != nil { + t.Fatalf("Set failed: %v", err) + } + } + + opts := storage.GetOptions{IgnoreNotFound: false} + defaultTier := makeTier(names.DefaultTierName, "", v3.DefaultTierOrder) + err := store.Get(ctx, "projectcalico.org/tiers/default", opts, defaultTier) + if err != nil { + t.Fatalf("Get failed: %v", err) + } + + anpTier := makeTier(names.AdminNetworkPolicyTierName, "", v3.AdminNetworkPolicyTierOrder) + err = store.Get(ctx, "projectcalico.org/tiers/adminnetworkpolicy", opts, anpTier) + if err != nil { + t.Fatalf("Get failed: %v", err) + } + + tests := []struct { + prefix string + pred storage.SelectionPredicate + expectedOut []*v3.Tier + }{{ // test List at cluster scope + prefix: "projectcalico.org/tiers/foo", + pred: storage.Everything, + expectedOut: []*v3.Tier{preset[0].storedObj}, + }, { // test List with tier name matching + prefix: "projectcalico.org/tiers/", + pred: storage.SelectionPredicate{ + Label: labels.Everything(), + Field: fields.ParseSelectorOrDie("metadata.name!=" + preset[0].storedObj.Name), + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + tier := obj.(*v3.Tier) + return nil, fields.Set{"metadata.name": tier.Name}, nil + }, + }, + expectedOut: []*v3.Tier{anpTier, preset[1].storedObj, defaultTier}, + }} + + for i, tt := range tests { + out := &v3.TierList{} + opts := storage.ListOptions{ResourceVersion: "0", Predicate: tt.pred} + err := store.List(ctx, tt.prefix, opts, out) + if err != nil { + t.Fatalf("List failed: %v", err) + } + if len(tt.expectedOut) != len(out.Items) { + t.Errorf("#%d: length of list want=%d, get=%d", i, len(tt.expectedOut), len(out.Items)) + continue + } + for j, wantTier := range tt.expectedOut { + getTier := &out.Items[j] + if !reflect.DeepEqual(wantTier, getTier) { + t.Errorf("#%d: tier want=%#v, get=%#v", i, wantTier, getTier) + } + } + } +} + +func testTierSetup(t *testing.T) (context.Context, *resourceStore) { + codec := apitesting.TestCodec(codecs, v3.SchemeGroupVersion) + cfg, err := apiconfig.LoadClientConfig("") + if err != nil { + klog.Errorf("Failed to load client config: %q", err) + os.Exit(1) + } + cfg.Spec.DatastoreType = "etcdv3" + cfg.Spec.EtcdEndpoints = "http://localhost:2379" + c, err := clientv3.New(*cfg) + if err != nil { + klog.Errorf("Failed creating client: %q", err) + os.Exit(1) + } + klog.Infof("Client: %v", c) + + opts := Options{ + RESTOptions: generic.RESTOptions{ + StorageConfig: &storagebackend.ConfigForResource{ + GroupResource: schema.GroupResource{ + Group: "projectcalico.org/v3", + Resource: "tiers", + }, + Config: storagebackend.Config{ + Codec: codec, + }, + }, + }, + } + store, _ := NewTierStorage(opts) + ctx := context.Background() + + return ctx, store.Storage.(*resourceStore) +} + +func testTierCleanup(t *testing.T, ctx context.Context, store *resourceStore) { + tr, _ := store.client.Tiers().Get(ctx, "default", options.GetOptions{}) + if tr != nil { + _, _ = store.client.Tiers().Delete(ctx, "foo", options.DeleteOptions{}) + } +} + +// testTierPropogateStore helps propogates store with objects, automates key generation, and returns +// keys and stored objects. +func testTierPropogateStore(ctx context.Context, t *testing.T, store *resourceStore, obj *v3.Tier) (string, *v3.Tier) { + // Setup store with a key and grab the output for returning. + key := "projectcalico.org/tiers/foo" + setOutput := &v3.Tier{} + err := store.Create(ctx, key, obj, setOutput, 0) + if err != nil { + t.Fatalf("Set failed: %v", err) + } + return key, setOutput +} + +func makeTierWithDefaults() *v3.Tier { + return makeTier("foo", "", 10.0) +} + +func makeTier(name, uid string, order float64) *v3.Tier { + meta := metav1.ObjectMeta{Name: name} + if uid != "" { + meta = metav1.ObjectMeta{Name: name, UID: types.UID(uid)} + } + return &v3.Tier{ + ObjectMeta: meta, + Spec: v3.TierSpec{ + Order: &order, + }, + } +} diff --git a/apiserver/pkg/storage/calico/watcher_test.go b/apiserver/pkg/storage/calico/watcher_test.go index 8db64af9ad3..77f905dc0b8 100644 --- a/apiserver/pkg/storage/calico/watcher_test.go +++ b/apiserver/pkg/storage/calico/watcher_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - calico "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/calico/libcalico-go/lib/options" @@ -36,14 +36,14 @@ func testWatch(t *testing.T, list bool) { ctx, store, gnpStore := testSetup(t) defer func() { testCleanup(t, ctx, store, gnpStore) - _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "foo", options.DeleteOptions{}) - _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "bar", options.DeleteOptions{}) + _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "default.foo", options.DeleteOptions{}) + _, _ = store.client.NetworkPolicies().Delete(ctx, "default", "default.bar", options.DeleteOptions{}) }() - policyFoo := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "foo"}} + policyFoo := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.foo"}} policyFoo.SetCreationTimestamp(metav1.Time{Time: time.Now()}) policyFoo.SetUID("test_uid_foo") - policyBar := &calico.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "bar"}} + policyBar := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "default.bar"}} policyBar.SetCreationTimestamp(metav1.Time{Time: time.Now()}) policyBar.SetUID("test_uid_bar") @@ -55,7 +55,7 @@ func testWatch(t *testing.T, list bool) { }{{ // create a key watchTests: []*testWatchStruct{ { - key: "projectcalico.org/networkpolicies/default/foo", + key: "projectcalico.org/networkpolicies/default/default.foo", obj: policyFoo, expectEvent: true, watchType: watch.Added, @@ -65,13 +65,13 @@ func testWatch(t *testing.T, list bool) { }, { // create a key but obj gets filtered. Then update it with unfiltered obj watchTests: []*testWatchStruct{ { - key: "projectcalico.org/networkpolicies/default/foo", + key: "projectcalico.org/networkpolicies/default/default.foo", obj: policyFoo, expectEvent: false, watchType: "", }, { - key: "projectcalico.org/networkpolicies/default/bar", + key: "projectcalico.org/networkpolicies/default/default.bar", obj: policyBar, expectEvent: true, watchType: watch.Added, @@ -79,9 +79,9 @@ func testWatch(t *testing.T, list bool) { }, pred: storage.SelectionPredicate{ Label: labels.Everything(), - Field: fields.ParseSelectorOrDie("metadata.name=bar"), + Field: fields.ParseSelectorOrDie("metadata.name=default.bar"), GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - policy := obj.(*calico.NetworkPolicy) + policy := obj.(*v3.NetworkPolicy) return nil, fields.Set{"metadata.name": policy.Name}, nil }, }, @@ -95,7 +95,7 @@ func testWatch(t *testing.T, list bool) { t.Fatalf("Watch failed: %v", err) } } - var prevObj *calico.NetworkPolicy + var prevObj *v3.NetworkPolicy for _, watchTest := range tt.watchTests { if !list { ns, name, err := NamespaceAndNameFromKey(watchTest.key, true) @@ -110,7 +110,7 @@ func testWatch(t *testing.T, list bool) { t.Fatalf("Watch failed: %v", err) } } - out := &calico.NetworkPolicy{} + out := &v3.NetworkPolicy{} err = store.GuaranteedUpdate(ctx, watchTest.key, out, true, nil, storage.SimpleUpdate( func(runtime.Object) (runtime.Object, error) { return watchTest.obj, nil @@ -141,7 +141,7 @@ func testWatch(t *testing.T, list bool) { type testWatchStruct struct { key string - obj *calico.NetworkPolicy + obj *v3.NetworkPolicy expectEvent bool watchType watch.EventType } @@ -157,7 +157,7 @@ func testCheckEventType(t *testing.T, expectEventType watch.EventType, w watch.I } } -func testCheckResult(t *testing.T, i int, expectEventType watch.EventType, w watch.Interface, expectObj *calico.NetworkPolicy) { +func testCheckResult(t *testing.T, i int, expectEventType watch.EventType, w watch.Interface, expectObj *v3.NetworkPolicy) { select { case res := <-w.ResultChan(): if res.Type != expectEventType { @@ -178,8 +178,8 @@ func testCheckStop(t *testing.T, i int, w watch.Interface) { if ok { var obj string switch e.Object.(type) { - case *calico.NetworkPolicy: - obj = e.Object.(*calico.NetworkPolicy).Name + case *v3.NetworkPolicy: + obj = e.Object.(*v3.NetworkPolicy).Name case *metav1.Status: obj = e.Object.(*metav1.Status).Message } diff --git a/apiserver/test/integration/clientset_test.go b/apiserver/test/integration/clientset_test.go index 5006e824c95..3be99eaaa4e 100644 --- a/apiserver/test/integration/clientset_test.go +++ b/apiserver/test/integration/clientset_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" @@ -84,7 +83,7 @@ func TestEtcdHealthCheckerSuccess(t *testing.T) { retryInterval := 500 * time.Millisecond for i := 0; i < 5; i++ { resp, err = c.Get(clientconfig.Host + "/healthz") - if nil != err || http.StatusOK != resp.StatusCode { + if err != nil || http.StatusOK != resp.StatusCode { success = false time.Sleep(retryInterval) } else { @@ -163,8 +162,9 @@ func TestNetworkPolicyClient(t *testing.T) { func testNetworkPolicyClient(client calicoclient.Interface, name string) error { ns := "default" + defaultTierPolicyName := "default" + "." + name policyClient := client.ProjectcalicoV3().NetworkPolicies(ns) - policy := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: name}} + policy := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: defaultTierPolicyName}} ctx := context.Background() // start from scratch @@ -179,26 +179,127 @@ func testNetworkPolicyClient(client calicoclient.Interface, name string) error { return fmt.Errorf("policies should not exist on start, had %v policies", len(policies.Items)) } - policyServer, err := policyClient.Create(ctx, policy, metav1.CreateOptions{}) - if nil != err { + // Create a policy without the "default" prefix. It should be defaulted by the apiserver. + policy2 := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: name}} + policyServer, err := policyClient.Create(ctx, policy2, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the policy '%v' (%v)", policy2, err) + } + if defaultTierPolicyName != policyServer.Name { + return fmt.Errorf("policy name prefix wasn't defaulted by the apiserver on create: %v", policyServer) + } + + // Update that policy. We should be able to use the same name that we used to create it (i.e., without the "default" prefix). + policyServer.Name = name + policyServer.Labels = map[string]string{"foo": "bar"} + policyServer, err = policyClient.Update(ctx, policyServer, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("error updating the policy '%v' (%v)", policyServer, err) + } + if defaultTierPolicyName != policyServer.Name { + return fmt.Errorf("policy name prefix wasn't defaulted by the apiserver on update: %v", policyServer) + } + + // Delete that policy. We should be able to use the same name that we used to create it (i.e., without the "default" prefix). + err = policyClient.Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("error deleting the policy '%v' (%v)", name, err) + } + + // Now create a policy with the "default" prefix. It should be created as-is. + policyServer, err = policyClient.Create(ctx, policy, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the policy '%v' (%v)", policy, err) + } + if defaultTierPolicyName != policyServer.Name { + return fmt.Errorf("didn't get the same policy back from the server \n%+v\n%+v", policy, policyServer) + } + + updatedPolicy := policyServer + updatedPolicy.Labels = map[string]string{"foo": "bar"} + policyServer, err = policyClient.Update(ctx, updatedPolicy, metav1.UpdateOptions{}) + if err != nil { return fmt.Errorf("error creating the policy '%v' (%v)", policy, err) } - if name != policyServer.Name { + if defaultTierPolicyName != policyServer.Name { return fmt.Errorf("didn't get the same policy back from the server \n%+v\n%+v", policy, policyServer) } - if policyServer.ResourceVersion == "" { - return fmt.Errorf("expected a non-empty resource version. RV=%s", policyServer.ResourceVersion) + + // For testing out Tiered Policy + tierClient := client.ProjectcalicoV3().Tiers() + order := float64(100.0) + tier := &v3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "net-sec"}, + Spec: v3.TierSpec{ + Order: &order, + }, } - policyServer.Labels = map[string]string{"foo": "bar"} - policyServer, err = policyClient.Update(ctx, policyServer, metav1.UpdateOptions{}) - if nil != err { - return fmt.Errorf("error updating the policy '%+v' (%v)", policy, err) + if _, err := tierClient.Create(ctx, tier, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("error creating tier '%v' (%v)", tier, err) + } + defer func() { + _ = tierClient.Delete(ctx, "net-sec", metav1.DeleteOptions{}) + }() + + netSecPolicyName := "net-sec" + "." + name + netSecPolicy := &v3.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: netSecPolicyName}, Spec: v3.NetworkPolicySpec{Tier: "net-sec"}} + policyServer, err = policyClient.Create(ctx, netSecPolicy, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the policy '%v' (%v)", netSecPolicy, err) } - if name != policyServer.Name { + if netSecPolicyName != policyServer.Name { return fmt.Errorf("didn't get the same policy back from the server \n%+v\n%+v", policy, policyServer) } + // Should be listing the policy under default tier. + policies, err = policyClient.List(ctx, metav1.ListOptions{FieldSelector: "spec.tier=default"}) + if err != nil { + return fmt.Errorf("error listing policies (%s)", err) + } + if len(policies.Items) != 1 { + return fmt.Errorf("should have exactly one policy, had %v policies", len(policies.Items)) + } + + // Should be listing the policy under "net-sec" tier + policies, err = policyClient.List(ctx, metav1.ListOptions{FieldSelector: "spec.tier=net-sec"}) + if err != nil { + return fmt.Errorf("error listing policies (%s)", err) + } + if len(policies.Items) != 1 { + return fmt.Errorf("should have exactly one policy, had %v policies", len(policies.Items)) + } + + // Should be listing all policy + policies, err = policyClient.List(ctx, metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("error listing policies (%s)", err) + } + if len(policies.Items) != 2 { + return fmt.Errorf("should have exactly two policies, had %v policies", len(policies.Items)) + } + + // Should be listing the policy under "net-sec" tier + policies, err = policyClient.List(ctx, metav1.ListOptions{LabelSelector: "projectcalico.org/tier in (net-sec)"}) + if err != nil { + return fmt.Errorf("error listing NetworkPolicies (%s)", err) + } + if len(policies.Items) != 1 { + return fmt.Errorf("should have exactly one policy, had %v policies", len(policies.Items)) + } + if policies.Items[0].Spec.Tier != "net-sec" { + return fmt.Errorf("should have list policy from net-sec tier, had %s tier", policies.Items[0].Spec.Tier) + } + + // Should be listing the policy under "net-sec" and "default tier + policies, err = policyClient.List(ctx, metav1.ListOptions{LabelSelector: "projectcalico.org/tier in (default, net-sec)"}) + if err != nil { + return fmt.Errorf("error listing NetworkPolicies (%s)", err) + } + if len(policies.Items) != 2 { + return fmt.Errorf("should have exactly two policies, had %v policies", len(policies.Items)) + } + policyServer, err = policyClient.Get(ctx, name, metav1.GetOptions{}) if err != nil { return fmt.Errorf("error getting policy %s (%s)", name, err) @@ -209,9 +310,9 @@ func testNetworkPolicyClient(client calicoclient.Interface, name string) error { } // Watch Test: - opts := v1.ListOptions{Watch: true} + opts := metav1.ListOptions{Watch: true} wIface, err := policyClient.Watch(ctx, opts) - if nil != err { + if err != nil { return fmt.Errorf("Error on watch") } var wg sync.WaitGroup @@ -225,7 +326,12 @@ func testNetworkPolicyClient(client calicoclient.Interface, name string) error { }() err = policyClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { + return fmt.Errorf("policy should be deleted (%s)", err) + } + + err = policyClient.Delete(ctx, netSecPolicyName, metav1.DeleteOptions{}) + if err != nil { return fmt.Errorf("policy should be deleted (%s)", err) } @@ -233,6 +339,76 @@ func testNetworkPolicyClient(client calicoclient.Interface, name string) error { return nil } +// TestTierClient exercises the Tier client. +func TestTierClient(t *testing.T) { + const name = "test-tier" + rootTestFunc := func() func(t *testing.T) { + return func(t *testing.T) { + client, shutdownServer := getFreshApiserverAndClient(t, func() runtime.Object { + return &v3.Tier{} + }) + defer shutdownServer() + if err := testTierClient(client, name); err != nil { + t.Fatal(err) + } + } + } + + if !t.Run(name, rootTestFunc()) { + t.Errorf("test-tier test failed") + } +} + +func testTierClient(client calicoclient.Interface, name string) error { + tierClient := client.ProjectcalicoV3().Tiers() + order := float64(100.0) + tier := &v3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v3.TierSpec{ + Order: &order, + }, + } + ctx := context.Background() + + // start from scratch + tiers, err := tierClient.List(ctx, metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("error listing tiers (%s)", err) + } + if tiers.Items == nil { + return fmt.Errorf("Items field should not be set to nil") + } + + tierServer, err := tierClient.Create(ctx, tier, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the tier '%v' (%v)", tier, err) + } + if name != tierServer.Name { + return fmt.Errorf("didn't get the same tier back from the server \n%+v\n%+v", tier, tierServer) + } + + _, err = tierClient.List(ctx, metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("error listing tiers (%s)", err) + } + + tierServer, err = tierClient.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("error getting tier %s (%s)", name, err) + } + if name != tierServer.Name && + tier.ResourceVersion == tierServer.ResourceVersion { + return fmt.Errorf("didn't get the same tier back from the server \n%+v\n%+v", tier, tierServer) + } + + err = tierClient.Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("tier should be deleted (%s)", err) + } + + return nil +} + // TestGlobalNetworkPolicyClient exercises the GlobalNetworkPolicy client. func TestGlobalNetworkPolicyClient(t *testing.T) { const name = "test-globalnetworkpolicy" @@ -255,7 +431,8 @@ func TestGlobalNetworkPolicyClient(t *testing.T) { func testGlobalNetworkPolicyClient(client calicoclient.Interface, name string) error { globalNetworkPolicyClient := client.ProjectcalicoV3().GlobalNetworkPolicies() - globalNetworkPolicy := &v3.GlobalNetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: name}} + defaultTierPolicyName := "default" + "." + name + globalNetworkPolicy := &v3.GlobalNetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: defaultTierPolicyName}} ctx := context.Background() // start from scratch @@ -267,20 +444,111 @@ func testGlobalNetworkPolicyClient(client calicoclient.Interface, name string) e return fmt.Errorf("Items field should not be set to nil") } - globalNetworkPolicyServer, err := globalNetworkPolicyClient.Create(ctx, globalNetworkPolicy, metav1.CreateOptions{}) - if nil != err { + // Test that we can create / update / delete policies using the non-tier prefixed name. + globalNetworkPolicy2 := &v3.GlobalNetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: name}} + globalNetworkPolicyServer, err := globalNetworkPolicyClient.Create(ctx, globalNetworkPolicy2, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the globalNetworkPolicy '%v' (%v)", globalNetworkPolicy2, err) + } + if defaultTierPolicyName != globalNetworkPolicyServer.Name { + return fmt.Errorf("policy name prefix wasn't defaulted by the apiserver on create: %v", globalNetworkPolicyServer) + } + globalNetworkPolicyServer.Name = name + globalNetworkPolicyServer.Labels = map[string]string{"foo": "bar"} + globalNetworkPolicyServer, err = globalNetworkPolicyClient.Update(ctx, globalNetworkPolicyServer, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("error updating the policy '%v' (%v)", globalNetworkPolicyServer, err) + } + if defaultTierPolicyName != globalNetworkPolicyServer.Name { + return fmt.Errorf("policy name prefix wasn't defaulted by the apiserver on update: %v", globalNetworkPolicyServer) + } + err = globalNetworkPolicyClient.Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("error deleting the policy '%v' (%v)", name, err) + } + + // Now use the tier prefixed name. + globalNetworkPolicyServer, err = globalNetworkPolicyClient.Create(ctx, globalNetworkPolicy, metav1.CreateOptions{}) + if err != nil { return fmt.Errorf("error creating the globalNetworkPolicy '%v' (%v)", globalNetworkPolicy, err) } - if name != globalNetworkPolicyServer.Name { + if defaultTierPolicyName != globalNetworkPolicyServer.Name { return fmt.Errorf("didn't get the same globalNetworkPolicy back from the server \n%+v\n%+v", globalNetworkPolicy, globalNetworkPolicyServer) } + // For testing out Tiered Policy + tierClient := client.ProjectcalicoV3().Tiers() + order := float64(100.0) + tier := &v3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "net-sec"}, + Spec: v3.TierSpec{ + Order: &order, + }, + } + + if _, err := tierClient.Create(ctx, tier, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("error creating tier '%v' (%v)", tier, err) + } + defer func() { + _ = tierClient.Delete(ctx, "net-sec", metav1.DeleteOptions{}) + }() + + netSecPolicyName := "net-sec" + "." + name + netSecPolicy := &v3.GlobalNetworkPolicy{ObjectMeta: metav1.ObjectMeta{Name: netSecPolicyName}, Spec: v3.GlobalNetworkPolicySpec{Tier: "net-sec"}} + globalNetworkPolicyServer, err = globalNetworkPolicyClient.Create(ctx, netSecPolicy, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the policy '%v' (%v)", netSecPolicy, err) + } + if netSecPolicyName != globalNetworkPolicyServer.Name { + return fmt.Errorf("didn't get the same policy back from the server \n%+v\n%+v", netSecPolicy, globalNetworkPolicyServer) + } + + // Should be listing the policy under "default" tier + globalNetworkPolicies, err = globalNetworkPolicyClient.List(ctx, metav1.ListOptions{FieldSelector: "spec.tier=default"}) + if err != nil { + return fmt.Errorf("error listing globalNetworkPolicies (%s)", err) + } + if len(globalNetworkPolicies.Items) != 1 { + return fmt.Errorf("should have exactly one policy, had %v policies", len(globalNetworkPolicies.Items)) + } + + // Should be listing the policy under "net-sec" tier + globalNetworkPolicies, err = globalNetworkPolicyClient.List(ctx, metav1.ListOptions{FieldSelector: "spec.tier=net-sec"}) + if err != nil { + return fmt.Errorf("error listing globalNetworkPolicies (%s)", err) + } + if len(globalNetworkPolicies.Items) != 1 { + return fmt.Errorf("should have exactly one policy, had %v policies", len(globalNetworkPolicies.Items)) + } + + // Should be listing all policies globalNetworkPolicies, err = globalNetworkPolicyClient.List(ctx, metav1.ListOptions{}) if err != nil { return fmt.Errorf("error listing globalNetworkPolicies (%s)", err) } + if len(globalNetworkPolicies.Items) != 2 { + return fmt.Errorf("should have exactly two policies, had %v policies", len(globalNetworkPolicies.Items)) + } + + // Should be listing the policy under "net-sec" tier + globalNetworkPolicies, err = globalNetworkPolicyClient.List(ctx, metav1.ListOptions{LabelSelector: "projectcalico.org/tier in (net-sec)"}) + if err != nil { + return fmt.Errorf("error listing stagedGlobalNetworkPolicies (%s)", err) + } if len(globalNetworkPolicies.Items) != 1 { - return fmt.Errorf("should have exactly one policies, had %v policies", len(globalNetworkPolicies.Items)) + return fmt.Errorf("should have exactly one policy, had %v policies", len(globalNetworkPolicies.Items)) + } + if globalNetworkPolicies.Items[0].Spec.Tier != "net-sec" { + return fmt.Errorf("should have list policy from net-sec tier, had %s tier", globalNetworkPolicies.Items[0].Spec.Tier) + } + + // Should be listing the policy under "net-sec" and "default tier + globalNetworkPolicies, err = globalNetworkPolicyClient.List(ctx, metav1.ListOptions{LabelSelector: "projectcalico.org/tier in (default, net-sec)"}) + if err != nil { + return fmt.Errorf("error listing stagedGlobalNetworkPolicies (%s)", err) + } + if len(globalNetworkPolicies.Items) != 2 { + return fmt.Errorf("should have exactly two policies, had %v policies", len(globalNetworkPolicies.Items)) } globalNetworkPolicyServer, err = globalNetworkPolicyClient.Get(ctx, name, metav1.GetOptions{}) @@ -293,10 +561,15 @@ func testGlobalNetworkPolicyClient(client calicoclient.Interface, name string) e } err = globalNetworkPolicyClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("globalNetworkPolicy should be deleted (%s)", err) } + err = globalNetworkPolicyClient.Delete(ctx, netSecPolicyName, metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("policy should be deleted (%s)", err) + } + return nil } @@ -337,7 +610,7 @@ func testGlobalNetworkSetClient(client calicoclient.Interface, name string) erro } globalNetworkSetServer, err := globalNetworkSetClient.Create(ctx, globalNetworkSet, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the globalNetworkSet '%v' (%v)", globalNetworkSet, err) } if name != globalNetworkSetServer.Name { @@ -359,7 +632,7 @@ func testGlobalNetworkSetClient(client calicoclient.Interface, name string) erro } err = globalNetworkSetClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("globalNetworkSet should be deleted (%s)", err) } @@ -405,14 +678,14 @@ func testNetworkSetClient(client calicoclient.Interface, name string) error { } networkSetServer, err := networkSetClient.Create(ctx, networkSet, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the networkSet '%v' (%v)", networkSet, err) } updatedNetworkSet := networkSetServer updatedNetworkSet.Labels = map[string]string{"foo": "bar"} _, err = networkSetClient.Update(ctx, updatedNetworkSet, metav1.UpdateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error updating the networkSet '%v' (%v)", networkSet, err) } @@ -435,9 +708,9 @@ func testNetworkSetClient(client calicoclient.Interface, name string) error { } // Watch Test: - opts := v1.ListOptions{Watch: true} + opts := metav1.ListOptions{Watch: true} wIface, err := networkSetClient.Watch(ctx, opts) - if nil != err { + if err != nil { return fmt.Errorf("Error on watch") } var wg sync.WaitGroup @@ -451,7 +724,7 @@ func testNetworkSetClient(client calicoclient.Interface, name string) error { }() err = networkSetClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("networkSet should be deleted (%s)", err) } @@ -459,6 +732,75 @@ func testNetworkSetClient(client calicoclient.Interface, name string) error { return nil } +// TestIPReservationClient exercises the IPReservation client. +func TestIPReservationClient(t *testing.T) { + const name = "test-ipreservation" + rootTestFunc := func() func(t *testing.T) { + return func(t *testing.T) { + client, shutdownServer := getFreshApiserverAndClient(t, func() runtime.Object { + return &v3.IPReservation{} + }) + defer shutdownServer() + if err := testIPReservationClient(client, name); err != nil { + t.Fatal(err) + } + } + } + + if !t.Run(name, rootTestFunc()) { + t.Errorf("test-ipreservation test failed") + } +} + +func testIPReservationClient(client calicoclient.Interface, name string) error { + ipreservationClient := client.ProjectcalicoV3().IPReservations() + ipreservation := &v3.IPReservation{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v3.IPReservationSpec{ + ReservedCIDRs: []string{"192.168.0.0/16"}, + }, + } + ctx := context.Background() + + // start from scratch + ipreservations, err := ipreservationClient.List(ctx, metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("error listing ipreservations (%s)", err) + } + if ipreservations.Items == nil { + return fmt.Errorf("items field should not be set to nil") + } + + ipreservationServer, err := ipreservationClient.Create(ctx, ipreservation, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating the ipreservation '%v' (%v)", ipreservation, err) + } + if name != ipreservationServer.Name { + return fmt.Errorf("didn't get the same ipreservation back from the server \n%+v\n%+v", ipreservation, ipreservationServer) + } + + _, err = ipreservationClient.List(ctx, metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("error listing ipreservations (%s)", err) + } + + ipreservationServer, err = ipreservationClient.Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("error getting ipreservation %s (%s)", name, err) + } + if name != ipreservationServer.Name && + ipreservation.ResourceVersion == ipreservationServer.ResourceVersion { + return fmt.Errorf("didn't get the same ipreservation back from the server \n%+v\n%+v", ipreservation, ipreservationServer) + } + + err = ipreservationClient.Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("ipreservation should be deleted (%s)", err) + } + + return nil +} + // TestHostEndpointClient exercises the HostEndpoint client. func TestHostEndpointClient(t *testing.T) { const name = "test-hostendpoint" @@ -471,6 +813,10 @@ func TestHostEndpointClient(t *testing.T) { }() rootTestFunc := func() func(t *testing.T) { return func(t *testing.T) { + client, shutdownServer := getFreshApiserverAndClient(t, func() runtime.Object { + return &v3.HostEndpoint{} + }) + defer shutdownServer() if err := testHostEndpointClient(client, name); err != nil { t.Fatal(err) } @@ -496,7 +842,7 @@ func deleteHostEndpointClient(client calicoclient.Interface, name string) error hostEndpointClient := client.ProjectcalicoV3().HostEndpoints() ctx := context.Background() - return hostEndpointClient.Delete(ctx, name, v1.DeleteOptions{}) + return hostEndpointClient.Delete(ctx, name, metav1.DeleteOptions{}) } func testHostEndpointClient(client calicoclient.Interface, name string) error { @@ -515,7 +861,7 @@ func testHostEndpointClient(client calicoclient.Interface, name string) error { } hostEndpointServer, err := hostEndpointClient.Create(ctx, hostEndpoint, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the hostEndpoint '%v' (%v)", hostEndpoint, err) } if name != hostEndpointServer.Name { @@ -540,12 +886,12 @@ func testHostEndpointClient(client calicoclient.Interface, name string) error { } err = hostEndpointClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("hostEndpoint should be deleted (%s)", err) } // Test watch - w, err := client.ProjectcalicoV3().HostEndpoints().Watch(ctx, v1.ListOptions{}) + w, err := client.ProjectcalicoV3().HostEndpoints().Watch(ctx, metav1.ListOptions{}) if err != nil { return fmt.Errorf("error watching HostEndpoints (%s)", err) } @@ -628,7 +974,7 @@ func testIPPoolClient(client calicoclient.Interface, name string) error { } ippoolServer, err := ippoolClient.Create(ctx, ippool, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the ippool '%v' (%v)", ippool, err) } if name != ippoolServer.Name { @@ -650,77 +996,8 @@ func testIPPoolClient(client calicoclient.Interface, name string) error { } err = ippoolClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { - return fmt.Errorf("ippool should be deleted (%s)", err) - } - - return nil -} - -// TestIPReservationClient exercises the IPReservation client. -func TestIPReservationClient(t *testing.T) { - const name = "test-ipreservation" - rootTestFunc := func() func(t *testing.T) { - return func(t *testing.T) { - client, shutdownServer := getFreshApiserverAndClient(t, func() runtime.Object { - return &v3.IPReservation{} - }) - defer shutdownServer() - if err := testIPReservationClient(client, name); err != nil { - t.Fatal(err) - } - } - } - - if !t.Run(name, rootTestFunc()) { - t.Errorf("test-ipreservation test failed") - } -} - -func testIPReservationClient(client calicoclient.Interface, name string) error { - ipreservationClient := client.ProjectcalicoV3().IPReservations() - ipreservation := &v3.IPReservation{ - ObjectMeta: metav1.ObjectMeta{Name: name}, - Spec: v3.IPReservationSpec{ - ReservedCIDRs: []string{"192.168.0.0/16"}, - }, - } - ctx := context.Background() - - // start from scratch - ipreservations, err := ipreservationClient.List(ctx, metav1.ListOptions{}) - if err != nil { - return fmt.Errorf("error listing ipreservations (%s)", err) - } - if ipreservations.Items == nil { - return fmt.Errorf("items field should not be set to nil") - } - - ipreservationServer, err := ipreservationClient.Create(ctx, ipreservation, metav1.CreateOptions{}) - if nil != err { - return fmt.Errorf("error creating the ipreservation '%v' (%v)", ipreservation, err) - } - if name != ipreservationServer.Name { - return fmt.Errorf("didn't get the same ipreservation back from the server \n%+v\n%+v", ipreservation, ipreservationServer) - } - - _, err = ipreservationClient.List(ctx, metav1.ListOptions{}) if err != nil { - return fmt.Errorf("error listing ipreservations (%s)", err) - } - - ipreservationServer, err = ipreservationClient.Get(ctx, name, metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("error getting ipreservation %s (%s)", name, err) - } - if name != ipreservationServer.Name && - ipreservation.ResourceVersion == ipreservationServer.ResourceVersion { - return fmt.Errorf("didn't get the same ipreservation back from the server \n%+v\n%+v", ipreservation, ipreservationServer) - } - - err = ipreservationClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { - return fmt.Errorf("ipreservation should be deleted (%s)", err) + return fmt.Errorf("ippool should be deleted (%s)", err) } return nil @@ -767,7 +1044,7 @@ func testBGPConfigurationClient(client calicoclient.Interface, name string) erro } bgpRes, err := bgpConfigClient.Create(ctx, bgpConfig, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the bgpConfiguration '%v' (%v)", bgpConfig, err) } if resName != bgpRes.Name { @@ -780,7 +1057,7 @@ func testBGPConfigurationClient(client calicoclient.Interface, name string) erro } err = bgpConfigClient.Delete(ctx, resName, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("BGPConfiguration should be deleted (%s)", err) } @@ -830,7 +1107,7 @@ func testBGPPeerClient(client calicoclient.Interface, name string) error { } bgpRes, err := bgpPeerClient.Create(ctx, bgpPeer, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the bgpPeer '%v' (%v)", bgpPeer, err) } if resName != bgpRes.Name { @@ -843,7 +1120,7 @@ func testBGPPeerClient(client calicoclient.Interface, name string) error { } err = bgpPeerClient.Delete(ctx, resName, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("BGPPeer should be deleted (%s)", err) } @@ -961,7 +1238,7 @@ func testFelixConfigurationClient(client calicoclient.Interface, name string) er } felixConfigServer, err := felixConfigClient.Create(ctx, felixConfig, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the felixConfig '%v' (%v)", felixConfig, err) } if name != felixConfigServer.Name { @@ -983,7 +1260,7 @@ func testFelixConfigurationClient(client calicoclient.Interface, name string) er } err = felixConfigClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("felixConfig should be deleted (%s)", err) } @@ -1036,7 +1313,7 @@ func testKubeControllersConfigurationClient(client calicoclient.Interface) error } kubeControllersConfigServer, err := kubeControllersConfigClient.Create(ctx, kubeControllersConfig, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the kubeControllersConfig '%v' (%v)", kubeControllersConfig, err) } if kubeControllersConfigServer.Name != "default" { @@ -1096,12 +1373,12 @@ func testKubeControllersConfigurationClient(client calicoclient.Interface) error } err = kubeControllersConfigClient.Delete(ctx, "default", metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("kubeControllersConfig should be deleted (%s)", err) } // Test watch - w, err := client.ProjectcalicoV3().KubeControllersConfigurations().Watch(ctx, v1.ListOptions{}) + w, err := client.ProjectcalicoV3().KubeControllersConfigurations().Watch(ctx, metav1.ListOptions{}) if err != nil { return fmt.Errorf("error watching KubeControllersConfigurations (%s)", err) } @@ -1126,11 +1403,11 @@ func testKubeControllersConfigurationClient(client calicoclient.Interface) error // Create, then delete KubeControllersConfigurations _, err = kubeControllersConfigClient.Create(ctx, kubeControllersConfig, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the kubeControllersConfig '%v' (%v)", kubeControllersConfig, err) } err = kubeControllersConfigClient.Delete(ctx, "default", metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("kubeControllersConfig should be deleted (%s)", err) } @@ -1193,6 +1470,7 @@ func testClusterInformationClient(client calicoclient.Interface, name string) er // Confirm it's not possible to create a clusterInformation obj with name other than "default" invalidClusterInfo := &v3.ClusterInformation{ObjectMeta: metav1.ObjectMeta{Name: "test-clusterinformation"}} + _, err = clusterInformationClient.Create(ctx, invalidClusterInfo, metav1.CreateOptions{}) if err == nil { return fmt.Errorf("expected error creating invalidClusterInfo with name other than \"default\"") @@ -1249,7 +1527,7 @@ func testCalicoNodeStatusClient(client calicoclient.Interface, name string) erro } caliconodestatusNew, err := caliconodestatusClient.Create(ctx, caliconodestatus, metav1.CreateOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("error creating the object '%v' (%v)", caliconodestatus, err) } if name != caliconodestatusNew.Name { @@ -1262,7 +1540,7 @@ func testCalicoNodeStatusClient(client calicoclient.Interface, name string) erro } err = caliconodestatusClient.Delete(ctx, name, metav1.DeleteOptions{}) - if nil != err { + if err != nil { return fmt.Errorf("object should be deleted (%s)", err) } @@ -1454,7 +1732,7 @@ func testBlockAffinityClient(client calicoclient.Interface, name string) error { } // Test watch - w, err := blockAffinityClient.Watch(ctx, v1.ListOptions{}) + w, err := blockAffinityClient.Watch(ctx, metav1.ListOptions{}) if err != nil { return fmt.Errorf("error watching block affinities (%s)", err) } @@ -1561,6 +1839,7 @@ func testBGPFilterClient(client calicoclient.Interface, name string) error { r5v4 := v3.BGPFilterRuleV4{ CIDR: "10.10.10.0/24", MatchOperator: v3.In, + Source: v3.BGPFilterSourceRemotePeers, Action: v3.Accept, } r5v6 := v3.BGPFilterRuleV6{ diff --git a/apiserver/test/integration/framework.go b/apiserver/test/integration/framework.go index 5b71ce0bd2c..0beeeae7420 100644 --- a/apiserver/test/integration/framework.go +++ b/apiserver/test/integration/framework.go @@ -71,6 +71,7 @@ func withConfigGetFreshApiserverServerAndClient( t.Logf("Starting server on port: %d", securePort) ro := genericoptions.NewRecommendedOptions(defaultEtcdPathPrefix, apiserver.Codecs.LegacyCodec(v3.SchemeGroupVersion)) ro.Etcd.StorageConfig.Transport.ServerList = serverConfig.etcdServerList + ro.Features.EnablePriorityAndFairness = false options := &server.CalicoServerOptions{ RecommendedOptions: ro, DisableAuth: true, diff --git a/apiserver/test/util/util.go b/apiserver/test/util/util.go index 95446a98c53..5d74d425efe 100644 --- a/apiserver/test/util/util.go +++ b/apiserver/test/util/util.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -62,3 +62,39 @@ func WaitForGlobalNetworkPoliciesToExist(client calicoclient.ProjectcalicoV3Inte }, ) } + +// WaitForTierToNotExist waits for the Tier with the given +// name to no longer exist. +func WaitForTierToNotExist(client calicoclient.ProjectcalicoV3Interface, name string) error { + return wait.PollUntilContextTimeout(context.Background(), 500*time.Millisecond, wait.ForeverTestTimeout, true, + func(ctx context.Context) (bool, error) { + klog.V(5).Infof("Waiting for serviceClass %v to not exist", name) + _, err := client.Tiers().Get(ctx, name, metav1.GetOptions{}) + if nil == err { + return false, nil + } + + if errors.IsNotFound(err) { + return true, nil + } + + return false, nil + }, + ) +} + +// WaitForTierToExist waits for the Tier with the given name +// to exist. +func WaitForTierToExist(client calicoclient.ProjectcalicoV3Interface, name string) error { + return wait.PollUntilContextTimeout(context.Background(), 500*time.Millisecond, wait.ForeverTestTimeout, true, + func(ctx context.Context) (bool, error) { + klog.V(5).Infof("Waiting for serviceClass %v to exist", name) + _, err := client.Tiers().Get(ctx, name, metav1.GetOptions{}) + if nil == err { + return true, nil + } + + return false, nil + }, + ) +} diff --git a/app-policy/cmd/dikastes/dikastes.go b/app-policy/cmd/dikastes/dikastes.go index 79a6303991d..eb6ddf4135e 100644 --- a/app-policy/cmd/dikastes/dikastes.go +++ b/app-policy/cmd/dikastes/dikastes.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -169,7 +169,7 @@ func runClient(arguments map[string]interface{}) { method := arguments[""].(string) opts := uds.GetDialOptions() - conn, err := grpc.Dial(dial, opts...) + conn, err := grpc.NewClient(dial, opts...) if err != nil { log.Fatalf("fail to dial: %v", err) } diff --git a/app-policy/cmd/healthz/healthz.go b/app-policy/cmd/healthz/healthz.go index 8c686c15827..c7a9031480c 100644 --- a/app-policy/cmd/healthz/healthz.go +++ b/app-policy/cmd/healthz/healthz.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ func main() { flag.Parse() opts := uds.GetDialOptions() - conn, err := grpc.Dial(dialPath, opts...) + conn, err := grpc.NewClient(dialPath, opts...) if err != nil { log.Fatalf("fail to dial: %v", err) } diff --git a/app-policy/syncher/syncserver.go b/app-policy/syncher/syncserver.go index 59cb89449c0..ee8f75b8a90 100644 --- a/app-policy/syncher/syncserver.go +++ b/app-policy/syncher/syncserver.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -89,7 +89,7 @@ func (s *syncClient) Sync(cxt context.Context, stores chan<- *policystore.Policy func (s *syncClient) syncStore(cxt context.Context, store *policystore.PolicyStore, inSync chan<- struct{}, done chan<- struct{}) { defer close(done) - conn, err := grpc.Dial(s.target, s.dialOpts...) + conn, err := grpc.NewClient(s.target, s.dialOpts...) if err != nil { log.Warnf("fail to dial Policy Sync server: %v", err) return diff --git a/app-policy/uds/uds.go b/app-policy/uds/uds.go index f16c1d64d83..83959b8a58d 100644 --- a/app-policy/uds/uds.go +++ b/app-policy/uds/uds.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,8 +20,13 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/resolver" ) +func init() { + resolver.SetDefaultScheme("passthrough") +} + func getDialer(proto string) func(context.Context, string) (net.Conn, error) { d := &net.Dialer{} return func(ctx context.Context, target string) (net.Conn, error) { diff --git a/calicoctl/Makefile b/calicoctl/Makefile index 11801a67d73..c114bf87e98 100644 --- a/calicoctl/Makefile +++ b/calicoctl/Makefile @@ -171,7 +171,7 @@ st: bin/calicoctl-linux-$(ARCH) version-helper $(MAKE) stop-kubernetes-master ## Run a local kubernetes master with API -# TODO: Commonize this with the functions in lib.Makefile. +# TODO: Commonize this with the functions in lib.Makefile. # For now, these tests do something special and launch two apiserver on different ports, so it makes sense # to keep them separate. run-kubernetes-master: stop-kubernetes-master @@ -233,7 +233,7 @@ run-kubernetes-master: stop-kubernetes-master -docker exec -ti st-apiserver-${KUBE_APISERVER_PORT} kubectl \ --server=https://127.0.0.1:${KUBE_APISERVER_PORT} \ create namespace test - + ## Stop the local kubernetes master stop-kubernetes-master: # Delete the cluster role binding. @@ -259,7 +259,7 @@ cd: image-all cd-common # Release ############################################################################### ## Produces a clean build of release artifacts at the specified version. -release-build: .release-$(VERSION).created +release-build: .release-$(VERSION).created .release-$(VERSION).created: $(MAKE) clean build-all image-all RELEASE=true $(MAKE) retag-build-images-with-registries IMAGETAG=$(VERSION) RELEASE=true diff --git a/calicoctl/calicoctl/commands/apply.go b/calicoctl/calicoctl/commands/apply.go index ac871eae04a..8d9871860f4 100644 --- a/calicoctl/calicoctl/commands/apply.go +++ b/calicoctl/calicoctl/commands/apply.go @@ -63,21 +63,7 @@ Description: Valid resource types are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * networkSet - * node - * profile - * workloadEndpoint - + When applying a resource: - if the resource does not already exist (as determined by it's primary identifiers) then it is created @@ -99,6 +85,9 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) diff --git a/calicoctl/calicoctl/commands/common/resources.go b/calicoctl/calicoctl/commands/common/resources.go index 36c04ba627c..e20b0964f9c 100644 --- a/calicoctl/calicoctl/commands/common/resources.go +++ b/calicoctl/calicoctl/commands/common/resources.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -234,6 +234,12 @@ func ExecuteConfigCommand(args map[string]interface{}, action action) CommandRes results.SingleKind = kind } + // For commands that modify config, first attempt to initialize the datastore. + switch action { + case ActionApply, ActionCreate, ActionUpdate: + tryEnsureInitialized(context.Background(), cclient) + } + // Now execute the command on each resource in order, exiting as soon as we hit an // error. export := argutils.ArgBoolOrFalse(args, "--export") @@ -338,6 +344,16 @@ func ExecuteResourceAction(args map[string]interface{}, client client.Interface, return []runtime.Object{resOut}, err } +// tryEnsureInitialized is called from any write action (apply, create, update). This +// attempts to initialize the datastore. We do not fail the user action if this fails +// since the users access permissions may be restricted to only allow modification +// of certain resource types. +func tryEnsureInitialized(ctx context.Context, client client.Interface) { + if err := client.EnsureInitialized(ctx, "", ""); err != nil { + log.WithError(err).Info("Unable to initialize datastore") + } +} + // handleNamespace fills in the namespace information in the resource (if required), // and validates the namespace depending on whether or not a namespace should be // provided based on the resource kind. diff --git a/calicoctl/calicoctl/commands/convert.go b/calicoctl/calicoctl/commands/convert.go index 428eb9a5f36..e03c08444ce 100644 --- a/calicoctl/calicoctl/commands/convert.go +++ b/calicoctl/calicoctl/commands/convert.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import ( "github.com/projectcalico/calico/calicoctl/calicoctl/commands/resourceloader" "github.com/projectcalico/calico/calicoctl/calicoctl/util" "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" + "github.com/projectcalico/calico/libcalico-go/lib/names" cconversion "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/upgrade/converters" @@ -217,10 +218,8 @@ func convertK8sResource(convResource unversioned.Resource) (converters.Resource, // Trim K8sNetworkPolicyNamePrefix from the policy name (the K8sNetworkPolicyToCalico // function adds it for when it is used for coexisting calico/k8s policies). - k8snp.Name = strings.TrimPrefix(k8snp.Name, cconversion.K8sNetworkPolicyNamePrefix) - + k8snp.Name = strings.TrimPrefix(k8snp.Name, names.K8sNetworkPolicyNamePrefix) res = k8snp - default: return nil, fmt.Errorf("conversion for the k8s resource type '%s' is not supported", k8sResKind) } @@ -241,6 +240,8 @@ func getTypeConverter(resKind string) (converters.Converter, error) { return converters.Profile{}, nil case "policy": return converters.Policy{}, nil + case "tier": + return converters.Tier{}, nil case "ippool": return converters.IPPool{}, nil case "bgppeer": diff --git a/calicoctl/calicoctl/commands/crds/crds.go b/calicoctl/calicoctl/commands/crds/crds.go index c13dee4d970..36e15108941 100644 --- a/calicoctl/calicoctl/commands/crds/crds.go +++ b/calicoctl/calicoctl/commands/crds/crds.go @@ -18,13 +18,13 @@ package crds const ( bgpconfigurations = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: bgpconfigurations.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: BGPConfiguration\n listKind: BGPConfigurationList\n plural: bgpconfigurations\n singular: bgpconfiguration\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n description: BGPConfiguration contains the configuration for any BGP routing.\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: BGPConfigurationSpec contains the values of the BGP configuration.\n properties:\n asNumber:\n description: 'ASNumber is the default AS number used by a node. [Default:\n 64512]'\n format: int32\n type: integer\n bindMode:\n description: BindMode indicates whether to listen for BGP connections\n on all addresses (None) or only on the node's canonical IP address\n Node.Spec.BGP.IPvXAddress (NodeIP). Default behaviour is to listen\n for BGP connections on all addresses.\n type: string\n communities:\n description: Communities is a list of BGP community values and their\n arbitrary names for tagging routes.\n items:\n description: Community contains standard or large community value\n and its name.\n properties:\n name:\n description: Name given to community value.\n type: string\n value:\n description: Value must be of format `aa:nn` or `aa:nn:mm`.\n For standard community use `aa:nn` format, where `aa` and\n `nn` are 16 bit number. For large community use `aa:nn:mm`\n format, where `aa`, `nn` and `mm` are 32 bit number. Where,\n `aa` is an AS Number, `nn` and `mm` are per-AS identifier.\n pattern: ^(\\d+):(\\d+)$|^(\\d+):(\\d+):(\\d+)$\n type: string\n type: object\n type: array\n ignoredInterfaces:\n description: IgnoredInterfaces indicates the network interfaces that\n needs to be excluded when reading device routes.\n items:\n type: string\n type: array\n listenPort:\n description: ListenPort is the port where BGP protocol should listen.\n Defaults to 179\n maximum: 65535\n minimum: 1\n type: integer\n logSeverityScreen:\n description: 'LogSeverityScreen is the log severity above which logs\n are sent to the stdout. [Default: INFO]'\n type: string\n nodeMeshMaxRestartTime:\n description: Time to allow for software restart for node-to-mesh peerings. When\n specified, this is configured as the graceful restart timeout. When\n not specified, the BIRD default of 120s is used. This field can\n only be set on the default BGPConfiguration instance and requires\n that NodeMesh is enabled\n type: string\n nodeMeshPassword:\n description: Optional BGP password for full node-to-mesh peerings.\n This field can only be set on the default BGPConfiguration instance\n and requires that NodeMesh is enabled\n properties:\n secretKeyRef:\n description: Selects a key of a secret in the node pod's namespace.\n properties:\n key:\n description: The key of the secret to select from. Must be\n a valid secret key.\n type: string\n name:\n description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n TODO: Add other useful fields. apiVersion, kind, uid?'\n type: string\n optional:\n description: Specify whether the Secret or its key must be\n defined\n type: boolean\n required:\n - key\n type: object\n type: object\n nodeToNodeMeshEnabled:\n description: 'NodeToNodeMeshEnabled sets whether full node to node\n BGP mesh is enabled. [Default: true]'\n type: boolean\n prefixAdvertisements:\n description: PrefixAdvertisements contains per-prefix advertisement\n configuration.\n items:\n description: PrefixAdvertisement configures advertisement properties\n for the specified CIDR.\n properties:\n cidr:\n description: CIDR for which properties should be advertised.\n type: string\n communities:\n description: Communities can be list of either community names\n already defined in `Specs.Communities` or community value\n of format `aa:nn` or `aa:nn:mm`. For standard community use\n `aa:nn` format, where `aa` and `nn` are 16 bit number. For\n large community use `aa:nn:mm` format, where `aa`, `nn` and\n `mm` are 32 bit number. Where,`aa` is an AS Number, `nn` and\n `mm` are per-AS identifier.\n items:\n type: string\n type: array\n type: object\n type: array\n serviceClusterIPs:\n description: ServiceClusterIPs are the CIDR blocks from which service\n cluster IPs are allocated. If specified, Calico will advertise these\n blocks, as well as any cluster IPs within them.\n items:\n description: ServiceClusterIPBlock represents a single allowed ClusterIP\n CIDR block.\n properties:\n cidr:\n type: string\n type: object\n type: array\n serviceExternalIPs:\n description: ServiceExternalIPs are the CIDR blocks for Kubernetes\n Service External IPs. Kubernetes Service ExternalIPs will only be\n advertised if they are within one of these blocks.\n items:\n description: ServiceExternalIPBlock represents a single allowed\n External IP CIDR block.\n properties:\n cidr:\n type: string\n type: object\n type: array\n serviceLoadBalancerIPs:\n description: ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes\n Service LoadBalancer IPs. Kubernetes Service status.LoadBalancer.Ingress\n IPs will only be advertised if they are within one of these blocks.\n items:\n description: ServiceLoadBalancerIPBlock represents a single allowed\n LoadBalancer IP CIDR block.\n properties:\n cidr:\n type: string\n type: object\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" - bgpfilters = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n annotations:\n controller-gen.kubebuilder.io/version: (devel)\n creationTimestamp: null\n name: bgpfilters.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: BGPFilter\n listKind: BGPFilterList\n plural: bgpfilters\n singular: bgpfilter\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: BGPFilterSpec contains the IPv4 and IPv6 filter rules of\n the BGP Filter.\n properties:\n exportV4:\n description: The ordered set of IPv4 BGPFilter rules acting on exporting\n routes to a peer.\n items:\n description: BGPFilterRuleV4 defines a BGP filter rule consisting\n a single IPv4 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n source:\n type: string\n required:\n - action\n type: object\n type: array\n exportV6:\n description: The ordered set of IPv6 BGPFilter rules acting on exporting\n routes to a peer.\n items:\n description: BGPFilterRuleV6 defines a BGP filter rule consisting\n a single IPv6 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n source:\n type: string\n required:\n - action\n type: object\n type: array\n importV4:\n description: The ordered set of IPv4 BGPFilter rules acting on importing\n routes from a peer.\n items:\n description: BGPFilterRuleV4 defines a BGP filter rule consisting\n a single IPv4 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n source:\n type: string\n required:\n - action\n type: object\n type: array\n importV6:\n description: The ordered set of IPv6 BGPFilter rules acting on importing\n routes from a peer.\n items:\n description: BGPFilterRuleV6 defines a BGP filter rule consisting\n a single IPv6 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n source:\n type: string\n required:\n - action\n type: object\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" + bgpfilters = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n annotations:\n controller-gen.kubebuilder.io/version: (devel)\n creationTimestamp: null\n name: bgpfilters.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: BGPFilter\n listKind: BGPFilterList\n plural: bgpfilters\n singular: bgpfilter\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: BGPFilterSpec contains the IPv4 and IPv6 filter rules of\n the BGP Filter.\n properties:\n exportV4:\n description: The ordered set of IPv4 BGPFilter rules acting on exporting\n routes to a peer.\n items:\n description: BGPFilterRuleV4 defines a BGP filter rule consisting\n a single IPv4 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n prefixLength:\n properties:\n max:\n format: int32\n maximum: 32\n minimum: 0\n type: integer\n min:\n format: int32\n maximum: 32\n minimum: 0\n type: integer\n type: object\n source:\n type: string\n required:\n - action\n type: object\n type: array\n exportV6:\n description: The ordered set of IPv6 BGPFilter rules acting on exporting\n routes to a peer.\n items:\n description: BGPFilterRuleV6 defines a BGP filter rule consisting\n a single IPv6 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n prefixLength:\n properties:\n max:\n format: int32\n maximum: 128\n minimum: 0\n type: integer\n min:\n format: int32\n maximum: 128\n minimum: 0\n type: integer\n type: object\n source:\n type: string\n required:\n - action\n type: object\n type: array\n importV4:\n description: The ordered set of IPv4 BGPFilter rules acting on importing\n routes from a peer.\n items:\n description: BGPFilterRuleV4 defines a BGP filter rule consisting\n a single IPv4 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n prefixLength:\n properties:\n max:\n format: int32\n maximum: 32\n minimum: 0\n type: integer\n min:\n format: int32\n maximum: 32\n minimum: 0\n type: integer\n type: object\n source:\n type: string\n required:\n - action\n type: object\n type: array\n importV6:\n description: The ordered set of IPv6 BGPFilter rules acting on importing\n routes from a peer.\n items:\n description: BGPFilterRuleV6 defines a BGP filter rule consisting\n a single IPv6 CIDR block and a filter action for this CIDR.\n properties:\n action:\n type: string\n cidr:\n type: string\n interface:\n type: string\n matchOperator:\n type: string\n prefixLength:\n properties:\n max:\n format: int32\n maximum: 128\n minimum: 0\n type: integer\n min:\n format: int32\n maximum: 128\n minimum: 0\n type: integer\n type: object\n source:\n type: string\n required:\n - action\n type: object\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" bgppeers = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: bgppeers.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: BGPPeer\n listKind: BGPPeerList\n plural: bgppeers\n singular: bgppeer\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: BGPPeerSpec contains the specification for a BGPPeer resource.\n properties:\n asNumber:\n description: The AS Number of the peer.\n format: int32\n type: integer\n filters:\n description: The ordered set of BGPFilters applied on this BGP peer.\n items:\n type: string\n type: array\n keepOriginalNextHop:\n description: Option to keep the original nexthop field when routes\n are sent to a BGP Peer. Setting \"true\" configures the selected BGP\n Peers node to use the \"next hop keep;\" instead of \"next hop self;\"(default)\n in the specific branch of the Node on \"bird.cfg\".\n type: boolean\n maxRestartTime:\n description: Time to allow for software restart. When specified,\n this is configured as the graceful restart timeout. When not specified,\n the BIRD default of 120s is used.\n type: string\n node:\n description: The node name identifying the Calico node instance that\n is targeted by this peer. If this is not set, and no nodeSelector\n is specified, then this BGP peer selects all nodes in the cluster.\n type: string\n nodeSelector:\n description: Selector for the nodes that should have this peering. When\n this is set, the Node field must be empty.\n type: string\n numAllowedLocalASNumbers:\n description: Maximum number of local AS numbers that are allowed in\n the AS path for received routes. This removes BGP loop prevention\n and should only be used if absolutely necessary.\n format: int32\n type: integer\n password:\n description: Optional BGP password for the peerings generated by this\n BGPPeer resource.\n properties:\n secretKeyRef:\n description: Selects a key of a secret in the node pod's namespace.\n properties:\n key:\n description: The key of the secret to select from. Must be\n a valid secret key.\n type: string\n name:\n description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n TODO: Add other useful fields. apiVersion, kind, uid?'\n type: string\n optional:\n description: Specify whether the Secret or its key must be\n defined\n type: boolean\n required:\n - key\n type: object\n type: object\n peerIP:\n description: The IP address of the peer followed by an optional port\n number to peer with. If port number is given, format should be `[]:port`\n or `:` for IPv4. If optional port number is not set,\n and this peer IP and ASNumber belongs to a calico/node with ListenPort\n set in BGPConfiguration, then we use that port to peer.\n type: string\n peerSelector:\n description: Selector for the remote nodes to peer with. When this\n is set, the PeerIP and ASNumber fields must be empty. For each\n peering between the local node and selected remote nodes, we configure\n an IPv4 peering if both ends have NodeBGPSpec.IPv4Address specified,\n and an IPv6 peering if both ends have NodeBGPSpec.IPv6Address specified. The\n remote AS number comes from the remote node's NodeBGPSpec.ASNumber,\n or the global default if that is not set.\n type: string\n reachableBy:\n description: Add an exact, i.e. /32, static route toward peer IP in\n order to prevent route flapping. ReachableBy contains the address\n of the gateway which peer can be reached by.\n type: string\n sourceAddress:\n description: Specifies whether and how to configure a source address\n for the peerings generated by this BGPPeer resource. Default value\n \"UseNodeIP\" means to configure the node IP as the source address. \"None\"\n means not to configure a source address.\n type: string\n ttlSecurity:\n description: TTLSecurity enables the generalized TTL security mechanism\n (GTSM) which protects against spoofed packets by ignoring received\n packets with a smaller than expected TTL value. The provided value\n is the number of hops (edges) between the peers.\n type: integer\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" blockaffinities = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: blockaffinities.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: BlockAffinity\n listKind: BlockAffinityList\n plural: blockaffinities\n singular: blockaffinity\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: BlockAffinitySpec contains the specification for a BlockAffinity\n resource.\n properties:\n cidr:\n type: string\n deleted:\n description: Deleted indicates that this block affinity is being deleted.\n This field is a string for compatibility with older releases that\n mistakenly treat this field as a string.\n type: string\n node:\n type: string\n state:\n type: string\n required:\n - cidr\n - deleted\n - node\n - state\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" caliconodestatuses = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n annotations:\n controller-gen.kubebuilder.io/version: (devel)\n creationTimestamp: null\n name: caliconodestatuses.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: CalicoNodeStatus\n listKind: CalicoNodeStatusList\n plural: caliconodestatuses\n singular: caliconodestatus\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: CalicoNodeStatusSpec contains the specification for a CalicoNodeStatus\n resource.\n properties:\n classes:\n description: Classes declares the types of information to monitor\n for this calico/node, and allows for selective status reporting\n about certain subsets of information.\n items:\n type: string\n type: array\n node:\n description: The node name identifies the Calico node instance for\n node status.\n type: string\n updatePeriodSeconds:\n description: UpdatePeriodSeconds is the period at which CalicoNodeStatus\n should be updated. Set to 0 to disable CalicoNodeStatus refresh.\n Maximum update period is one day.\n format: int32\n type: integer\n type: object\n status:\n description: CalicoNodeStatusStatus defines the observed state of CalicoNodeStatus.\n No validation needed for status since it is updated by Calico.\n properties:\n agent:\n description: Agent holds agent status on the node.\n properties:\n birdV4:\n description: BIRDV4 represents the latest observed status of bird4.\n properties:\n lastBootTime:\n description: LastBootTime holds the value of lastBootTime\n from bird.ctl output.\n type: string\n lastReconfigurationTime:\n description: LastReconfigurationTime holds the value of lastReconfigTime\n from bird.ctl output.\n type: string\n routerID:\n description: Router ID used by bird.\n type: string\n state:\n description: The state of the BGP Daemon.\n type: string\n version:\n description: Version of the BGP daemon\n type: string\n type: object\n birdV6:\n description: BIRDV6 represents the latest observed status of bird6.\n properties:\n lastBootTime:\n description: LastBootTime holds the value of lastBootTime\n from bird.ctl output.\n type: string\n lastReconfigurationTime:\n description: LastReconfigurationTime holds the value of lastReconfigTime\n from bird.ctl output.\n type: string\n routerID:\n description: Router ID used by bird.\n type: string\n state:\n description: The state of the BGP Daemon.\n type: string\n version:\n description: Version of the BGP daemon\n type: string\n type: object\n type: object\n bgp:\n description: BGP holds node BGP status.\n properties:\n numberEstablishedV4:\n description: The total number of IPv4 established bgp sessions.\n type: integer\n numberEstablishedV6:\n description: The total number of IPv6 established bgp sessions.\n type: integer\n numberNotEstablishedV4:\n description: The total number of IPv4 non-established bgp sessions.\n type: integer\n numberNotEstablishedV6:\n description: The total number of IPv6 non-established bgp sessions.\n type: integer\n peersV4:\n description: PeersV4 represents IPv4 BGP peers status on the node.\n items:\n description: CalicoNodePeer contains the status of BGP peers\n on the node.\n properties:\n peerIP:\n description: IP address of the peer whose condition we are\n reporting.\n type: string\n since:\n description: Since the state or reason last changed.\n type: string\n state:\n description: State is the BGP session state.\n type: string\n type:\n description: Type indicates whether this peer is configured\n via the node-to-node mesh, or via en explicit global or\n per-node BGPPeer object.\n type: string\n type: object\n type: array\n peersV6:\n description: PeersV6 represents IPv6 BGP peers status on the node.\n items:\n description: CalicoNodePeer contains the status of BGP peers\n on the node.\n properties:\n peerIP:\n description: IP address of the peer whose condition we are\n reporting.\n type: string\n since:\n description: Since the state or reason last changed.\n type: string\n state:\n description: State is the BGP session state.\n type: string\n type:\n description: Type indicates whether this peer is configured\n via the node-to-node mesh, or via en explicit global or\n per-node BGPPeer object.\n type: string\n type: object\n type: array\n required:\n - numberEstablishedV4\n - numberEstablishedV6\n - numberNotEstablishedV4\n - numberNotEstablishedV6\n type: object\n lastUpdated:\n description: LastUpdated is a timestamp representing the server time\n when CalicoNodeStatus object last updated. It is represented in\n RFC3339 form and is in UTC.\n format: date-time\n nullable: true\n type: string\n routes:\n description: Routes reports routes known to the Calico BGP daemon\n on the node.\n properties:\n routesV4:\n description: RoutesV4 represents IPv4 routes on the node.\n items:\n description: CalicoNodeRoute contains the status of BGP routes\n on the node.\n properties:\n destination:\n description: Destination of the route.\n type: string\n gateway:\n description: Gateway for the destination.\n type: string\n interface:\n description: Interface for the destination\n type: string\n learnedFrom:\n description: LearnedFrom contains information regarding\n where this route originated.\n properties:\n peerIP:\n description: If sourceType is NodeMesh or BGPPeer, IP\n address of the router that sent us this route.\n type: string\n sourceType:\n description: Type of the source where a route is learned\n from.\n type: string\n type: object\n type:\n description: Type indicates if the route is being used for\n forwarding or not.\n type: string\n type: object\n type: array\n routesV6:\n description: RoutesV6 represents IPv6 routes on the node.\n items:\n description: CalicoNodeRoute contains the status of BGP routes\n on the node.\n properties:\n destination:\n description: Destination of the route.\n type: string\n gateway:\n description: Gateway for the destination.\n type: string\n interface:\n description: Interface for the destination\n type: string\n learnedFrom:\n description: LearnedFrom contains information regarding\n where this route originated.\n properties:\n peerIP:\n description: If sourceType is NodeMesh or BGPPeer, IP\n address of the router that sent us this route.\n type: string\n sourceType:\n description: Type of the source where a route is learned\n from.\n type: string\n type: object\n type:\n description: Type indicates if the route is being used for\n forwarding or not.\n type: string\n type: object\n type: array\n type: object\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" clusterinformations = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: clusterinformations.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: ClusterInformation\n listKind: ClusterInformationList\n plural: clusterinformations\n singular: clusterinformation\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n description: ClusterInformation contains the cluster specific information.\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: ClusterInformationSpec contains the values of describing\n the cluster.\n properties:\n calicoVersion:\n description: CalicoVersion is the version of Calico that the cluster\n is running\n type: string\n clusterGUID:\n description: ClusterGUID is the GUID of the cluster\n type: string\n clusterType:\n description: ClusterType describes the type of the cluster\n type: string\n datastoreReady:\n description: DatastoreReady is used during significant datastore migrations\n to signal to components such as Felix that it should wait before\n accessing the datastore.\n type: boolean\n variant:\n description: Variant declares which variant of Calico should be active.\n type: string\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" - felixconfigurations = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: felixconfigurations.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: FelixConfiguration\n listKind: FelixConfigurationList\n plural: felixconfigurations\n singular: felixconfiguration\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n description: Felix Configuration contains the configuration for Felix.\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: FelixConfigurationSpec contains the values of the Felix configuration.\n properties:\n allowIPIPPacketsFromWorkloads:\n description: 'AllowIPIPPacketsFromWorkloads controls whether Felix\n will add a rule to drop IPIP encapsulated traffic from workloads\n [Default: false]'\n type: boolean\n allowVXLANPacketsFromWorkloads:\n description: 'AllowVXLANPacketsFromWorkloads controls whether Felix\n will add a rule to drop VXLAN encapsulated traffic from workloads\n [Default: false]'\n type: boolean\n awsSrcDstCheck:\n description: 'Set source-destination-check on AWS EC2 instances. Accepted\n value must be one of \"DoNothing\", \"Enable\" or \"Disable\". [Default:\n DoNothing]'\n enum:\n - DoNothing\n - Enable\n - Disable\n type: string\n bpfCTLBLogFilter:\n description: 'BPFCTLBLogFilter specifies, what is logged by connect\n time load balancer when BPFLogLevel is debug. Currently has to be\n specified as ''all'' when BPFLogFilters is set to see CTLB logs.\n [Default: unset - means logs are emitted when BPFLogLevel id debug\n and BPFLogFilters not set.]'\n type: string\n bpfConnectTimeLoadBalancing:\n description: 'BPFConnectTimeLoadBalancing when in BPF mode, controls\n whether Felix installs the connect-time load balancer. The connect-time\n load balancer is required for the host to be able to reach Kubernetes\n services and it improves the performance of pod-to-service connections.When\n set to TCP, connect time load balancing is available only for services\n with TCP ports. [Default: TCP]'\n enum:\n - TCP\n - Enabled\n - Disabled\n type: string\n bpfConnectTimeLoadBalancingEnabled:\n description: 'BPFConnectTimeLoadBalancingEnabled when in BPF mode,\n controls whether Felix installs the connection-time load balancer. The\n connect-time load balancer is required for the host to be able to\n reach Kubernetes services and it improves the performance of pod-to-service\n connections. The only reason to disable it is for debugging purposes.\n This will be deprecated. Use BPFConnectTimeLoadBalancing [Default:\n true]'\n type: boolean\n bpfDSROptoutCIDRs:\n description: BPFDSROptoutCIDRs is a list of CIDRs which are excluded\n from DSR. That is, clients in those CIDRs will accesses nodeports\n as if BPFExternalServiceMode was set to Tunnel.\n items:\n type: string\n type: array\n bpfDataIfacePattern:\n description: BPFDataIfacePattern is a regular expression that controls\n which interfaces Felix should attach BPF programs to in order to\n catch traffic to/from the network. This needs to match the interfaces\n that Calico workload traffic flows over as well as any interfaces\n that handle incoming traffic to nodeports and services from outside\n the cluster. It should not match the workload interfaces (usually\n named cali...).\n type: string\n bpfDisableGROForIfaces:\n description: BPFDisableGROForIfaces is a regular expression that controls\n which interfaces Felix should disable the Generic Receive Offload\n [GRO] option. It should not match the workload interfaces (usually\n named cali...).\n type: string\n bpfDisableUnprivileged:\n description: 'BPFDisableUnprivileged, if enabled, Felix sets the kernel.unprivileged_bpf_disabled\n sysctl to disable unprivileged use of BPF. This ensures that unprivileged\n users cannot access Calico''s BPF maps and cannot insert their own\n BPF programs to interfere with Calico''s. [Default: true]'\n type: boolean\n bpfEnabled:\n description: 'BPFEnabled, if enabled Felix will use the BPF dataplane.\n [Default: false]'\n type: boolean\n bpfEnforceRPF:\n description: 'BPFEnforceRPF enforce strict RPF on all host interfaces\n with BPF programs regardless of what is the per-interfaces or global\n setting. Possible values are Disabled, Strict or Loose. [Default:\n Loose]'\n pattern: ^(?i)(Disabled|Strict|Loose)?$\n type: string\n bpfExcludeCIDRsFromNAT:\n description: BPFExcludeCIDRsFromNAT is a list of CIDRs that are to\n be excluded from NAT resolution so that host can handle them. A\n typical usecase is node local DNS cache.\n items:\n type: string\n type: array\n bpfExtToServiceConnmark:\n description: 'BPFExtToServiceConnmark in BPF mode, control a 32bit\n mark that is set on connections from an external client to a local\n service. This mark allows us to control how packets of that connection\n are routed within the host and how is routing interpreted by RPF\n check. [Default: 0]'\n type: integer\n bpfExternalServiceMode:\n description: 'BPFExternalServiceMode in BPF mode, controls how connections\n from outside the cluster to services (node ports and cluster IPs)\n are forwarded to remote workloads. If set to \"Tunnel\" then both\n request and response traffic is tunneled to the remote node. If\n set to \"DSR\", the request traffic is tunneled but the response traffic\n is sent directly from the remote node. In \"DSR\" mode, the remote\n node appears to use the IP of the ingress node; this requires a\n permissive L2 network. [Default: Tunnel]'\n pattern: ^(?i)(Tunnel|DSR)?$\n type: string\n bpfForceTrackPacketsFromIfaces:\n description: 'BPFForceTrackPacketsFromIfaces in BPF mode, forces traffic\n from these interfaces to skip Calico''s iptables NOTRACK rule, allowing\n traffic from those interfaces to be tracked by Linux conntrack. Should\n only be used for interfaces that are not used for the Calico fabric. For\n example, a docker bridge device for non-Calico-networked containers.\n [Default: docker+]'\n items:\n type: string\n type: array\n bpfHostConntrackBypass:\n description: 'BPFHostConntrackBypass Controls whether to bypass Linux\n conntrack in BPF mode for workloads and services. [Default: true\n - bypass Linux conntrack]'\n type: boolean\n bpfHostNetworkedNATWithoutCTLB:\n description: 'BPFHostNetworkedNATWithoutCTLB when in BPF mode, controls\n whether Felix does a NAT without CTLB. This along with BPFConnectTimeLoadBalancing\n determines the CTLB behavior. [Default: Enabled]'\n enum:\n - Enabled\n - Disabled\n type: string\n bpfKubeProxyEndpointSlicesEnabled:\n description: BPFKubeProxyEndpointSlicesEnabled is deprecated and has\n no effect. BPF kube-proxy always accepts endpoint slices. This option\n will be removed in the next release.\n type: boolean\n bpfKubeProxyIptablesCleanupEnabled:\n description: 'BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF\n mode, Felix will proactively clean up the upstream Kubernetes kube-proxy''s\n iptables chains. Should only be enabled if kube-proxy is not running. [Default:\n true]'\n type: boolean\n bpfKubeProxyMinSyncPeriod:\n description: 'BPFKubeProxyMinSyncPeriod, in BPF mode, controls the\n minimum time between updates to the dataplane for Felix''s embedded\n kube-proxy. Lower values give reduced set-up latency. Higher values\n reduce Felix CPU usage by batching up more work. [Default: 1s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n bpfL3IfacePattern:\n description: BPFL3IfacePattern is a regular expression that allows\n to list tunnel devices like wireguard or vxlan (i.e., L3 devices)\n in addition to BPFDataIfacePattern. That is, tunnel interfaces not\n created by Calico, that Calico workload traffic flows over as well\n as any interfaces that handle incoming traffic to nodeports and\n services from outside the cluster.\n type: string\n bpfLogFilters:\n additionalProperties:\n type: string\n description: \"BPFLogFilters is a map of key=values where the value\n is a pcap filter expression and the key is an interface name with\n 'all' denoting all interfaces, 'weps' all workload endpoints and\n 'heps' all host endpoints. \\n When specified as an env var, it accepts\n a comma-separated list of key=values. [Default: unset - means all\n debug logs are emitted]\"\n type: object\n bpfLogLevel:\n description: 'BPFLogLevel controls the log level of the BPF programs\n when in BPF dataplane mode. One of \"Off\", \"Info\", or \"Debug\". The\n logs are emitted to the BPF trace pipe, accessible with the command\n `tc exec bpf debug`. [Default: Off].'\n pattern: ^(?i)(Off|Info|Debug)?$\n type: string\n bpfMapSizeConntrack:\n description: 'BPFMapSizeConntrack sets the size for the conntrack\n map. This map must be large enough to hold an entry for each active\n connection. Warning: changing the size of the conntrack map can\n cause disruption.'\n type: integer\n bpfMapSizeIPSets:\n description: BPFMapSizeIPSets sets the size for ipsets map. The IP\n sets map must be large enough to hold an entry for each endpoint\n matched by every selector in the source/destination matches in network\n policy. Selectors such as \"all()\" can result in large numbers of\n entries (one entry per endpoint in that case).\n type: integer\n bpfMapSizeIfState:\n description: BPFMapSizeIfState sets the size for ifstate map. The\n ifstate map must be large enough to hold an entry for each device\n (host + workloads) on a host.\n type: integer\n bpfMapSizeNATAffinity:\n type: integer\n bpfMapSizeNATBackend:\n description: BPFMapSizeNATBackend sets the size for nat back end map.\n This is the total number of endpoints. This is mostly more than\n the size of the number of services.\n type: integer\n bpfMapSizeNATFrontend:\n description: BPFMapSizeNATFrontend sets the size for nat front end\n map. FrontendMap should be large enough to hold an entry for each\n nodeport, external IP and each port in each service.\n type: integer\n bpfMapSizeRoute:\n description: BPFMapSizeRoute sets the size for the routes map. The\n routes map should be large enough to hold one entry per workload\n and a handful of entries per host (enough to cover its own IPs and\n tunnel IPs).\n type: integer\n bpfPSNATPorts:\n anyOf:\n - type: integer\n - type: string\n description: 'BPFPSNATPorts sets the range from which we randomly\n pick a port if there is a source port collision. This should be\n within the ephemeral range as defined by RFC 6056 (1024–65535) and\n preferably outside the ephemeral ranges used by common operating\n systems. Linux uses 32768–60999, while others mostly use the IANA\n defined range 49152–65535. It is not necessarily a problem if this\n range overlaps with the operating systems. Both ends of the range\n are inclusive. [Default: 20000:29999]'\n pattern: ^.*\n x-kubernetes-int-or-string: true\n bpfPolicyDebugEnabled:\n description: BPFPolicyDebugEnabled when true, Felix records detailed\n information about the BPF policy programs, which can be examined\n with the calico-bpf command-line tool.\n type: boolean\n chainInsertMode:\n description: 'ChainInsertMode controls whether Felix hooks the kernel''s\n top-level iptables chains by inserting a rule at the top of the\n chain or by appending a rule at the bottom. insert is the safe default\n since it prevents Calico''s rules from being bypassed. If you switch\n to append mode, be sure that the other rules in the chains signal\n acceptance by falling through to the Calico rules, otherwise the\n Calico policy will be bypassed. [Default: insert]'\n pattern: ^(?i)(insert|append)?$\n type: string\n dataplaneDriver:\n description: DataplaneDriver filename of the external dataplane driver\n to use. Only used if UseInternalDataplaneDriver is set to false.\n type: string\n dataplaneWatchdogTimeout:\n description: \"DataplaneWatchdogTimeout is the readiness/liveness timeout\n used for Felix's (internal) dataplane driver. Increase this value\n if you experience spurious non-ready or non-live events when Felix\n is under heavy load. Decrease the value to get felix to report non-live\n or non-ready more quickly. [Default: 90s] \\n Deprecated: replaced\n by the generic HealthTimeoutOverrides.\"\n type: string\n debugDisableLogDropping:\n type: boolean\n debugHost:\n description: DebugHost is the host IP or hostname to bind the debug\n port to. Only used if DebugPort is set. [Default:localhost]\n type: string\n debugMemoryProfilePath:\n type: string\n debugPort:\n description: DebugPort if set, enables Felix's debug HTTP port, which\n allows memory and CPU profiles to be retrieved. The debug port\n is not secure, it should not be exposed to the internet.\n type: integer\n debugSimulateCalcGraphHangAfter:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n debugSimulateDataplaneApplyDelay:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n debugSimulateDataplaneHangAfter:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n defaultEndpointToHostAction:\n description: 'DefaultEndpointToHostAction controls what happens to\n traffic that goes from a workload endpoint to the host itself (after\n the traffic hits the endpoint egress policy). By default Calico\n blocks traffic from workload endpoints to the host itself with an\n iptables \"DROP\" action. If you want to allow some or all traffic\n from endpoint to host, set this parameter to RETURN or ACCEPT. Use\n RETURN if you have your own rules in the iptables \"INPUT\" chain;\n Calico will insert its rules at the top of that chain, then \"RETURN\"\n packets to the \"INPUT\" chain once it has completed processing workload\n endpoint egress policy. Use ACCEPT to unconditionally accept packets\n from workloads after processing workload endpoint egress policy.\n [Default: Drop]'\n pattern: ^(?i)(Drop|Accept|Return)?$\n type: string\n deviceRouteProtocol:\n description: This defines the route protocol added to programmed device\n routes, by default this will be RTPROT_BOOT when left blank.\n type: integer\n deviceRouteSourceAddress:\n description: This is the IPv4 source address to use on programmed\n device routes. By default the source address is left blank, leaving\n the kernel to choose the source address used.\n type: string\n deviceRouteSourceAddressIPv6:\n description: This is the IPv6 source address to use on programmed\n device routes. By default the source address is left blank, leaving\n the kernel to choose the source address used.\n type: string\n disableConntrackInvalidCheck:\n type: boolean\n endpointReportingDelay:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n endpointReportingEnabled:\n type: boolean\n endpointStatusPathPrefix:\n description: \"EndpointStatusPathPrefix is the path to the directory\n where endpoint status will be written. Endpoint status file reporting\n is disabled if field is left empty. \\n Chosen directory should match\n the directory used by the CNI for PodStartupDelay. [Default: \\\"\\\"]\"\n type: string\n externalNodesList:\n description: ExternalNodesCIDRList is a list of CIDR's of external-non-calico-nodes\n which may source tunnel traffic and have the tunneled traffic be\n accepted at calico nodes.\n items:\n type: string\n type: array\n failsafeInboundHostPorts:\n description: 'FailsafeInboundHostPorts is a list of PortProto struct\n objects including UDP/TCP/SCTP ports and CIDRs that Felix will allow\n incoming traffic to host endpoints on irrespective of the security\n policy. This is useful to avoid accidentally cutting off a host\n with incorrect configuration. For backwards compatibility, if the\n protocol is not specified, it defaults to \"tcp\". If a CIDR is not\n specified, it will allow traffic from all addresses. To disable\n all inbound host ports, use the value \"[]\". The default value allows\n ssh access, DHCP, BGP, etcd and the Kubernetes API. [Default: tcp:22,\n udp:68, tcp:179, tcp:2379, tcp:2380, tcp:5473, tcp:6443, tcp:6666,\n tcp:6667 ]'\n items:\n description: ProtoPort is combination of protocol, port, and CIDR.\n Protocol and port must be specified.\n properties:\n net:\n type: string\n port:\n type: integer\n protocol:\n type: string\n required:\n - port\n - protocol\n type: object\n type: array\n failsafeOutboundHostPorts:\n description: 'FailsafeOutboundHostPorts is a list of List of PortProto\n struct objects including UDP/TCP/SCTP ports and CIDRs that Felix\n will allow outgoing traffic from host endpoints to irrespective\n of the security policy. This is useful to avoid accidentally cutting\n off a host with incorrect configuration. For backwards compatibility,\n if the protocol is not specified, it defaults to \"tcp\". If a CIDR\n is not specified, it will allow traffic from all addresses. To disable\n all outbound host ports, use the value \"[]\". The default value opens\n etcd''s standard ports to ensure that Felix does not get cut off\n from etcd as well as allowing DHCP, DNS, BGP and the Kubernetes\n API. [Default: udp:53, udp:67, tcp:179, tcp:2379, tcp:2380, tcp:5473,\n tcp:6443, tcp:6666, tcp:6667 ]'\n items:\n description: ProtoPort is combination of protocol, port, and CIDR.\n Protocol and port must be specified.\n properties:\n net:\n type: string\n port:\n type: integer\n protocol:\n type: string\n required:\n - port\n - protocol\n type: object\n type: array\n featureDetectOverride:\n description: FeatureDetectOverride is used to override feature detection\n based on auto-detected platform capabilities. Values are specified\n in a comma separated list with no spaces, example; \"SNATFullyRandom=true,MASQFullyRandom=false,RestoreSupportsLock=\". \"true\"\n or \"false\" will force the feature, empty or omitted values are auto-detected.\n pattern: ^([a-zA-Z0-9-_]+=(true|false|),)*([a-zA-Z0-9-_]+=(true|false|))?$\n type: string\n featureGates:\n description: FeatureGates is used to enable or disable tech-preview\n Calico features. Values are specified in a comma separated list\n with no spaces, example; \"BPFConnectTimeLoadBalancingWorkaround=enabled,XyZ=false\".\n This is used to enable features that are not fully production ready.\n pattern: ^([a-zA-Z0-9-_]+=([^=]+),)*([a-zA-Z0-9-_]+=([^=]+))?$\n type: string\n floatingIPs:\n description: FloatingIPs configures whether or not Felix will program\n non-OpenStack floating IP addresses. (OpenStack-derived floating\n IPs are always programmed, regardless of this setting.)\n enum:\n - Enabled\n - Disabled\n type: string\n genericXDPEnabled:\n description: 'GenericXDPEnabled enables Generic XDP so network cards\n that don''t support XDP offload or driver modes can use XDP. This\n is not recommended since it doesn''t provide better performance\n than iptables. [Default: false]'\n type: boolean\n goGCThreshold:\n description: \"GoGCThreshold Sets the Go runtime's garbage collection\n threshold. I.e. the percentage that the heap is allowed to grow\n before garbage collection is triggered. In general, doubling the\n value halves the CPU time spent doing GC, but it also doubles peak\n GC memory overhead. A special value of -1 can be used to disable\n GC entirely; this should only be used in conjunction with the GoMemoryLimitMB\n setting. \\n This setting is overridden by the GOGC environment variable.\n \\n [Default: 40]\"\n type: integer\n goMaxProcs:\n description: \"GoMaxProcs sets the maximum number of CPUs that the\n Go runtime will use concurrently. A value of -1 means \\\"use the\n system default\\\"; typically the number of real CPUs on the system.\n \\n this setting is overridden by the GOMAXPROCS environment variable.\n \\n [Default: -1]\"\n type: integer\n goMemoryLimitMB:\n description: \"GoMemoryLimitMB sets a (soft) memory limit for the Go\n runtime in MB. The Go runtime will try to keep its memory usage\n under the limit by triggering GC as needed. To avoid thrashing,\n it will exceed the limit if GC starts to take more than 50% of the\n process's CPU time. A value of -1 disables the memory limit. \\n\n Note that the memory limit, if used, must be considerably less than\n any hard resource limit set at the container or pod level. This\n is because felix is not the only process that must run in the container\n or pod. \\n This setting is overridden by the GOMEMLIMIT environment\n variable. \\n [Default: -1]\"\n type: integer\n healthEnabled:\n type: boolean\n healthHost:\n type: string\n healthPort:\n type: integer\n healthTimeoutOverrides:\n description: HealthTimeoutOverrides allows the internal watchdog timeouts\n of individual subcomponents to be overridden. This is useful for\n working around \"false positive\" liveness timeouts that can occur\n in particularly stressful workloads or if CPU is constrained. For\n a list of active subcomponents, see Felix's logs.\n items:\n properties:\n name:\n type: string\n timeout:\n type: string\n required:\n - name\n - timeout\n type: object\n type: array\n interfaceExclude:\n description: 'InterfaceExclude is a comma-separated list of interfaces\n that Felix should exclude when monitoring for host endpoints. The\n default value ensures that Felix ignores Kubernetes'' IPVS dummy\n interface, which is used internally by kube-proxy. If you want to\n exclude multiple interface names using a single value, the list\n supports regular expressions. For regular expressions you must wrap\n the value with ''/''. For example having values ''/^kube/,veth1''\n will exclude all interfaces that begin with ''kube'' and also the\n interface ''veth1''. [Default: kube-ipvs0]'\n type: string\n interfacePrefix:\n description: 'InterfacePrefix is the interface name prefix that identifies\n workload endpoints and so distinguishes them from host endpoint\n interfaces. Note: in environments other than bare metal, the orchestrators\n configure this appropriately. For example our Kubernetes and Docker\n integrations set the ''cali'' value, and our OpenStack integration\n sets the ''tap'' value. [Default: cali]'\n type: string\n interfaceRefreshInterval:\n description: InterfaceRefreshInterval is the period at which Felix\n rescans local interfaces to verify their state. The rescan can be\n disabled by setting the interval to 0.\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n ipipEnabled:\n description: 'IPIPEnabled overrides whether Felix should configure\n an IPIP interface on the host. Optional as Felix determines this\n based on the existing IP pools. [Default: nil (unset)]'\n type: boolean\n ipipMTU:\n description: 'IPIPMTU is the MTU to set on the tunnel device. See\n Configuring MTU [Default: 1440]'\n type: integer\n ipsetsRefreshInterval:\n description: 'IpsetsRefreshInterval is the period at which Felix re-checks\n all iptables state to ensure that no other process has accidentally\n broken Calico''s rules. Set to 0 to disable iptables refresh. [Default:\n 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesBackend:\n description: IptablesBackend specifies which backend of iptables will\n be used. The default is Auto.\n pattern: ^(?i)(Auto|FelixConfiguration|FelixConfigurationList|Legacy|NFT)?$\n type: string\n iptablesFilterAllowAction:\n pattern: ^(?i)(Accept|Return)?$\n type: string\n iptablesFilterDenyAction:\n description: IptablesFilterDenyAction controls what happens to traffic\n that is denied by network policy. By default Calico blocks traffic\n with an iptables \"DROP\" action. If you want to use \"REJECT\" action\n instead you can configure it in here.\n pattern: ^(?i)(Drop|Reject)?$\n type: string\n iptablesLockFilePath:\n description: 'IptablesLockFilePath is the location of the iptables\n lock file. You may need to change this if the lock file is not in\n its standard location (for example if you have mapped it into Felix''s\n container at a different path). [Default: /run/xtables.lock]'\n type: string\n iptablesLockProbeInterval:\n description: 'IptablesLockProbeInterval is the time that Felix will\n wait between attempts to acquire the iptables lock if it is not\n available. Lower values make Felix more responsive when the lock\n is contended, but use more CPU. [Default: 50ms]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesLockTimeout:\n description: 'IptablesLockTimeout is the time that Felix will wait\n for the iptables lock, or 0, to disable. To use this feature, Felix\n must share the iptables lock file with all other processes that\n also take the lock. When running Felix inside a container, this\n requires the /run directory of the host to be mounted into the calico/node\n or calico/felix container. [Default: 0s disabled]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesMangleAllowAction:\n pattern: ^(?i)(Accept|Return)?$\n type: string\n iptablesMarkMask:\n description: 'IptablesMarkMask is the mask that Felix selects its\n IPTables Mark bits from. Should be a 32 bit hexadecimal number with\n at least 8 bits set, none of which clash with any other mark bits\n in use on the system. [Default: 0xff000000]'\n format: int32\n type: integer\n iptablesNATOutgoingInterfaceFilter:\n type: string\n iptablesPostWriteCheckInterval:\n description: 'IptablesPostWriteCheckInterval is the period after Felix\n has done a write to the dataplane that it schedules an extra read\n back in order to check the write was not clobbered by another process.\n This should only occur if another application on the system doesn''t\n respect the iptables lock. [Default: 1s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesRefreshInterval:\n description: 'IptablesRefreshInterval is the period at which Felix\n re-checks the IP sets in the dataplane to ensure that no other process\n has accidentally broken Calico''s rules. Set to 0 to disable IP\n sets refresh. Note: the default for this value is lower than the\n other refresh intervals as a workaround for a Linux kernel bug that\n was fixed in kernel version 4.11. If you are using v4.11 or greater\n you may want to set this to, a higher value to reduce Felix CPU\n usage. [Default: 10s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n ipv6Support:\n description: IPv6Support controls whether Felix enables support for\n IPv6 (if supported by the in-use dataplane).\n type: boolean\n kubeNodePortRanges:\n description: 'KubeNodePortRanges holds list of port ranges used for\n service node ports. Only used if felix detects kube-proxy running\n in ipvs mode. Felix uses these ranges to separate host and workload\n traffic. [Default: 30000:32767].'\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n logDebugFilenameRegex:\n description: LogDebugFilenameRegex controls which source code files\n have their Debug log output included in the logs. Only logs from\n files with names that match the given regular expression are included. The\n filter only applies to Debug level logs.\n type: string\n logFilePath:\n description: 'LogFilePath is the full path to the Felix log. Set to\n none to disable file logging. [Default: /var/log/calico/felix.log]'\n type: string\n logPrefix:\n description: 'LogPrefix is the log prefix that Felix uses when rendering\n LOG rules. [Default: calico-packet]'\n type: string\n logSeverityFile:\n description: 'LogSeverityFile is the log severity above which logs\n are sent to the log file. [Default: Info]'\n pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$\n type: string\n logSeverityScreen:\n description: 'LogSeverityScreen is the log severity above which logs\n are sent to the stdout. [Default: Info]'\n pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$\n type: string\n logSeveritySys:\n description: 'LogSeveritySys is the log severity above which logs\n are sent to the syslog. Set to None for no logging to syslog. [Default:\n Info]'\n pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$\n type: string\n maxIpsetSize:\n type: integer\n metadataAddr:\n description: 'MetadataAddr is the IP address or domain name of the\n server that can answer VM queries for cloud-init metadata. In OpenStack,\n this corresponds to the machine running nova-api (or in Ubuntu,\n nova-api-metadata). A value of none (case-insensitive) means that\n Felix should not set up any NAT rule for the metadata path. [Default:\n 127.0.0.1]'\n type: string\n metadataPort:\n description: 'MetadataPort is the port of the metadata server. This,\n combined with global.MetadataAddr (if not ''None''), is used to\n set up a NAT rule, from 169.254.169.254:80 to MetadataAddr:MetadataPort.\n In most cases this should not need to be changed [Default: 8775].'\n type: integer\n mtuIfacePattern:\n description: MTUIfacePattern is a regular expression that controls\n which interfaces Felix should scan in order to calculate the host's\n MTU. This should not match workload interfaces (usually named cali...).\n type: string\n natOutgoingAddress:\n description: NATOutgoingAddress specifies an address to use when performing\n source NAT for traffic in a natOutgoing pool that is leaving the\n network. By default the address used is an address on the interface\n the traffic is leaving on (ie it uses the iptables MASQUERADE target)\n type: string\n natPortRange:\n anyOf:\n - type: integer\n - type: string\n description: NATPortRange specifies the range of ports that is used\n for port mapping when doing outgoing NAT. When unset the default\n behavior of the network stack is used.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n netlinkTimeout:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n nftablesMode:\n description: 'NFTablesMode configures nftables support in Felix. [Default:\n Disabled]'\n type: string\n openstackRegion:\n description: 'OpenstackRegion is the name of the region that a particular\n Felix belongs to. In a multi-region Calico/OpenStack deployment,\n this must be configured somehow for each Felix (here in the datamodel,\n or in felix.cfg or the environment on each compute node), and must\n match the [calico] openstack_region value configured in neutron.conf\n on each node. [Default: Empty]'\n type: string\n policySyncPathPrefix:\n description: 'PolicySyncPathPrefix is used to by Felix to communicate\n policy changes to external services, like Application layer policy.\n [Default: Empty]'\n type: string\n prometheusGoMetricsEnabled:\n description: 'PrometheusGoMetricsEnabled disables Go runtime metrics\n collection, which the Prometheus client does by default, when set\n to false. This reduces the number of metrics reported, reducing\n Prometheus load. [Default: true]'\n type: boolean\n prometheusMetricsEnabled:\n description: 'PrometheusMetricsEnabled enables the Prometheus metrics\n server in Felix if set to true. [Default: false]'\n type: boolean\n prometheusMetricsHost:\n description: 'PrometheusMetricsHost is the host that the Prometheus\n metrics server should bind to. [Default: empty]'\n type: string\n prometheusMetricsPort:\n description: 'PrometheusMetricsPort is the TCP port that the Prometheus\n metrics server should bind to. [Default: 9091]'\n type: integer\n prometheusProcessMetricsEnabled:\n description: 'PrometheusProcessMetricsEnabled disables process metrics\n collection, which the Prometheus client does by default, when set\n to false. This reduces the number of metrics reported, reducing\n Prometheus load. [Default: true]'\n type: boolean\n prometheusWireGuardMetricsEnabled:\n description: 'PrometheusWireGuardMetricsEnabled disables wireguard\n metrics collection, which the Prometheus client does by default,\n when set to false. This reduces the number of metrics reported,\n reducing Prometheus load. [Default: true]'\n type: boolean\n removeExternalRoutes:\n description: Whether or not to remove device routes that have not\n been programmed by Felix. Disabling this will allow external applications\n to also add device routes. This is enabled by default which means\n we will remove externally added routes.\n type: boolean\n reportingInterval:\n description: 'ReportingInterval is the interval at which Felix reports\n its status into the datastore or 0 to disable. Must be non-zero\n in OpenStack deployments. [Default: 30s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n reportingTTL:\n description: 'ReportingTTL is the time-to-live setting for process-wide\n status reports. [Default: 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n routeRefreshInterval:\n description: 'RouteRefreshInterval is the period at which Felix re-checks\n the routes in the dataplane to ensure that no other process has\n accidentally broken Calico''s rules. Set to 0 to disable route refresh.\n [Default: 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n routeSource:\n description: 'RouteSource configures where Felix gets its routing\n information. - WorkloadIPs: use workload endpoints to construct\n routes. - CalicoIPAM: the default - use IPAM data to construct routes.'\n pattern: ^(?i)(WorkloadIPs|CalicoIPAM)?$\n type: string\n routeSyncDisabled:\n description: RouteSyncDisabled will disable all operations performed\n on the route table. Set to true to run in network-policy mode only.\n type: boolean\n routeTableRange:\n description: Deprecated in favor of RouteTableRanges. Calico programs\n additional Linux route tables for various purposes. RouteTableRange\n specifies the indices of the route tables that Calico should use.\n properties:\n max:\n type: integer\n min:\n type: integer\n required:\n - max\n - min\n type: object\n routeTableRanges:\n description: Calico programs additional Linux route tables for various\n purposes. RouteTableRanges specifies a set of table index ranges\n that Calico should use. Deprecates`RouteTableRange`, overrides `RouteTableRange`.\n items:\n properties:\n max:\n type: integer\n min:\n type: integer\n required:\n - max\n - min\n type: object\n type: array\n serviceLoopPrevention:\n description: 'When service IP advertisement is enabled, prevent routing\n loops to service IPs that are not in use, by dropping or rejecting\n packets that do not get DNAT''d by kube-proxy. Unless set to \"Disabled\",\n in which case such routing loops continue to be allowed. [Default:\n Drop]'\n pattern: ^(?i)(Drop|Reject|Disabled)?$\n type: string\n sidecarAccelerationEnabled:\n description: 'SidecarAccelerationEnabled enables experimental sidecar\n acceleration [Default: false]'\n type: boolean\n usageReportingEnabled:\n description: 'UsageReportingEnabled reports anonymous Calico version\n number and cluster size to projectcalico.org. Logs warnings returned\n by the usage server. For example, if a significant security vulnerability\n has been discovered in the version of Calico being used. [Default:\n true]'\n type: boolean\n usageReportingInitialDelay:\n description: 'UsageReportingInitialDelay controls the minimum delay\n before Felix makes a report. [Default: 300s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n usageReportingInterval:\n description: 'UsageReportingInterval controls the interval at which\n Felix makes reports. [Default: 86400s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n useInternalDataplaneDriver:\n description: UseInternalDataplaneDriver, if true, Felix will use its\n internal dataplane programming logic. If false, it will launch\n an external dataplane driver and communicate with it over protobuf.\n type: boolean\n vxlanEnabled:\n description: 'VXLANEnabled overrides whether Felix should create the\n VXLAN tunnel device for IPv4 VXLAN networking. Optional as Felix\n determines this based on the existing IP pools. [Default: nil (unset)]'\n type: boolean\n vxlanMTU:\n description: 'VXLANMTU is the MTU to set on the IPv4 VXLAN tunnel\n device. See Configuring MTU [Default: 1410]'\n type: integer\n vxlanMTUV6:\n description: 'VXLANMTUV6 is the MTU to set on the IPv6 VXLAN tunnel\n device. See Configuring MTU [Default: 1390]'\n type: integer\n vxlanPort:\n type: integer\n vxlanVNI:\n type: integer\n windowsManageFirewallRules:\n description: 'WindowsManageFirewallRules configures whether or not\n Felix will program Windows Firewall rules. (to allow inbound access\n to its own metrics ports) [Default: Disabled]'\n enum:\n - Enabled\n - Disabled\n type: string\n wireguardEnabled:\n description: 'WireguardEnabled controls whether Wireguard is enabled\n for IPv4 (encapsulating IPv4 traffic over an IPv4 underlay network).\n [Default: false]'\n type: boolean\n wireguardEnabledV6:\n description: 'WireguardEnabledV6 controls whether Wireguard is enabled\n for IPv6 (encapsulating IPv6 traffic over an IPv6 underlay network).\n [Default: false]'\n type: boolean\n wireguardHostEncryptionEnabled:\n description: 'WireguardHostEncryptionEnabled controls whether Wireguard\n host-to-host encryption is enabled. [Default: false]'\n type: boolean\n wireguardInterfaceName:\n description: 'WireguardInterfaceName specifies the name to use for\n the IPv4 Wireguard interface. [Default: wireguard.cali]'\n type: string\n wireguardInterfaceNameV6:\n description: 'WireguardInterfaceNameV6 specifies the name to use for\n the IPv6 Wireguard interface. [Default: wg-v6.cali]'\n type: string\n wireguardKeepAlive:\n description: 'WireguardKeepAlive controls Wireguard PersistentKeepalive\n option. Set 0 to disable. [Default: 0]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n wireguardListeningPort:\n description: 'WireguardListeningPort controls the listening port used\n by IPv4 Wireguard. [Default: 51820]'\n type: integer\n wireguardListeningPortV6:\n description: 'WireguardListeningPortV6 controls the listening port\n used by IPv6 Wireguard. [Default: 51821]'\n type: integer\n wireguardMTU:\n description: 'WireguardMTU controls the MTU on the IPv4 Wireguard\n interface. See Configuring MTU [Default: 1440]'\n type: integer\n wireguardMTUV6:\n description: 'WireguardMTUV6 controls the MTU on the IPv6 Wireguard\n interface. See Configuring MTU [Default: 1420]'\n type: integer\n wireguardRoutingRulePriority:\n description: 'WireguardRoutingRulePriority controls the priority value\n to use for the Wireguard routing rule. [Default: 99]'\n type: integer\n workloadSourceSpoofing:\n description: WorkloadSourceSpoofing controls whether pods can use\n the allowedSourcePrefixes annotation to send traffic with a source\n IP address that is not theirs. This is disabled by default. When\n set to \"Any\", pods can request any prefix.\n pattern: ^(?i)(Disabled|Any)?$\n type: string\n xdpEnabled:\n description: 'XDPEnabled enables XDP acceleration for suitable untracked\n incoming deny rules. [Default: true]'\n type: boolean\n xdpRefreshInterval:\n description: 'XDPRefreshInterval is the period at which Felix re-checks\n all XDP state to ensure that no other process has accidentally broken\n Calico''s BPF maps or attached programs. Set to 0 to disable XDP\n refresh. [Default: 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" - globalnetworkpolicies = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: globalnetworkpolicies.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: GlobalNetworkPolicy\n listKind: GlobalNetworkPolicyList\n plural: globalnetworkpolicies\n singular: globalnetworkpolicy\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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 properties:\n applyOnForward:\n description: ApplyOnForward indicates to apply the rules in this policy\n on forward traffic.\n type: boolean\n doNotTrack:\n description: DoNotTrack indicates whether packets matched by the rules\n in this policy should go through the data plane's connection tracking,\n such as Linux conntrack. If True, the rules in this policy are\n applied before any data plane connection tracking, and packets allowed\n by this policy are marked as not to be tracked.\n type: boolean\n egress:\n description: The ordered set of egress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n ingress:\n description: The ordered set of ingress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n namespaceSelector:\n description: NamespaceSelector is an optional field for an expression\n used to select a pod based on namespaces.\n type: string\n order:\n description: Order is an optional field that specifies the order in\n which the policy is applied. Policies with higher \"order\" are applied\n after those with lower order. If the order is omitted, it may be\n considered to be \"infinite\" - i.e. the policy will be applied last. Policies\n with identical order will be applied in alphanumerical order based\n on the Policy \"Name\".\n type: number\n performanceHints:\n description: \"PerformanceHints contains a list of hints to Calico's\n policy engine to help process the policy more efficiently. Hints\n never change the enforcement behaviour of the policy. \\n Currently,\n the only available hint is \\\"AssumeNeededOnEveryNode\\\". When that\n hint is set on a policy, Felix will act as if the policy matches\n a local endpoint even if it does not. This is useful for \\\"preloading\\\"\n any large static policies that are known to be used on every node.\n If the policy is _not_ used on a particular node then the work done\n to preload the policy (and to maintain it) is wasted.\"\n items:\n type: string\n type: array\n preDNAT:\n description: PreDNAT indicates to apply the rules in this policy before\n any DNAT.\n type: boolean\n selector:\n description: \"The selector is an expression used to pick out the endpoints\n that the policy should be applied to. \\n Selector expressions follow\n this syntax: \\n \\tlabel == \\\"string_literal\\\" -> comparison, e.g.\n my_label == \\\"foo bar\\\" \\tlabel != \\\"string_literal\\\" -> not\n equal; also matches if label is not present \\tlabel in { \\\"a\\\",\n \\\"b\\\", \\\"c\\\", ... } -> true if the value of label X is one of\n \\\"a\\\", \\\"b\\\", \\\"c\\\" \\tlabel not in { \\\"a\\\", \\\"b\\\", \\\"c\\\", ... }\n \\ -> true if the value of label X is not one of \\\"a\\\", \\\"b\\\", \\\"c\\\"\n \\thas(label_name) -> True if that label is present \\t! expr ->\n negation of expr \\texpr && expr -> Short-circuit and \\texpr ||\n expr -> Short-circuit or \\t( expr ) -> parens for grouping \\tall()\n or the empty selector -> matches all endpoints. \\n Label names are\n allowed to contain alphanumerics, -, _ and /. String literals are\n more permissive but they do not support escape characters. \\n Examples\n (with made-up labels): \\n \\ttype == \\\"webserver\\\" && deployment\n == \\\"prod\\\" \\ttype in {\\\"frontend\\\", \\\"backend\\\"} \\tdeployment !=\n \\\"dev\\\" \\t! has(label_name)\"\n type: string\n serviceAccountSelector:\n description: ServiceAccountSelector is an optional field for an expression\n used to select a pod based on service accounts.\n type: string\n types:\n description: \"Types indicates whether this policy applies to ingress,\n or to egress, or to both. When not explicitly specified (and so\n the value on creation is empty or nil), Calico defaults Types according\n to what Ingress and Egress rules are present in the policy. The\n default is: \\n - [ PolicyTypeIngress ], if there are no Egress rules\n (including the case where there are also no Ingress rules) \\n\n - [ PolicyTypeEgress ], if there are Egress rules but no Ingress\n rules \\n - [ PolicyTypeIngress, PolicyTypeEgress ], if there are\n both Ingress and Egress rules. \\n When the policy is read back again,\n Types will always be one of these values, never empty or nil.\"\n items:\n description: PolicyType enumerates the possible values of the PolicySpec\n Types field.\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" + felixconfigurations = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: felixconfigurations.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: FelixConfiguration\n listKind: FelixConfigurationList\n plural: felixconfigurations\n singular: felixconfiguration\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n description: Felix Configuration contains the configuration for Felix.\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: FelixConfigurationSpec contains the values of the Felix configuration.\n properties:\n allowIPIPPacketsFromWorkloads:\n description: 'AllowIPIPPacketsFromWorkloads controls whether Felix\n will add a rule to drop IPIP encapsulated traffic from workloads\n [Default: false]'\n type: boolean\n allowVXLANPacketsFromWorkloads:\n description: 'AllowVXLANPacketsFromWorkloads controls whether Felix\n will add a rule to drop VXLAN encapsulated traffic from workloads\n [Default: false]'\n type: boolean\n awsSrcDstCheck:\n description: 'Set source-destination-check on AWS EC2 instances. Accepted\n value must be one of \"DoNothing\", \"Enable\" or \"Disable\". [Default:\n DoNothing]'\n enum:\n - DoNothing\n - Enable\n - Disable\n type: string\n bpfCTLBLogFilter:\n description: 'BPFCTLBLogFilter specifies, what is logged by connect\n time load balancer when BPFLogLevel is debug. Currently has to be\n specified as ''all'' when BPFLogFilters is set to see CTLB logs.\n [Default: unset - means logs are emitted when BPFLogLevel id debug\n and BPFLogFilters not set.]'\n type: string\n bpfConnectTimeLoadBalancing:\n description: 'BPFConnectTimeLoadBalancing when in BPF mode, controls\n whether Felix installs the connect-time load balancer. The connect-time\n load balancer is required for the host to be able to reach Kubernetes\n services and it improves the performance of pod-to-service connections.When\n set to TCP, connect time load balancing is available only for services\n with TCP ports. [Default: TCP]'\n enum:\n - TCP\n - Enabled\n - Disabled\n type: string\n bpfConnectTimeLoadBalancingEnabled:\n description: 'BPFConnectTimeLoadBalancingEnabled when in BPF mode,\n controls whether Felix installs the connection-time load balancer. The\n connect-time load balancer is required for the host to be able to\n reach Kubernetes services and it improves the performance of pod-to-service\n connections. The only reason to disable it is for debugging purposes.\n This will be deprecated. Use BPFConnectTimeLoadBalancing [Default:\n true]'\n type: boolean\n bpfDSROptoutCIDRs:\n description: BPFDSROptoutCIDRs is a list of CIDRs which are excluded\n from DSR. That is, clients in those CIDRs will accesses nodeports\n as if BPFExternalServiceMode was set to Tunnel.\n items:\n type: string\n type: array\n bpfDataIfacePattern:\n description: BPFDataIfacePattern is a regular expression that controls\n which interfaces Felix should attach BPF programs to in order to\n catch traffic to/from the network. This needs to match the interfaces\n that Calico workload traffic flows over as well as any interfaces\n that handle incoming traffic to nodeports and services from outside\n the cluster. It should not match the workload interfaces (usually\n named cali...).\n type: string\n bpfDisableGROForIfaces:\n description: BPFDisableGROForIfaces is a regular expression that controls\n which interfaces Felix should disable the Generic Receive Offload\n [GRO] option. It should not match the workload interfaces (usually\n named cali...).\n type: string\n bpfDisableUnprivileged:\n description: 'BPFDisableUnprivileged, if enabled, Felix sets the kernel.unprivileged_bpf_disabled\n sysctl to disable unprivileged use of BPF. This ensures that unprivileged\n users cannot access Calico''s BPF maps and cannot insert their own\n BPF programs to interfere with Calico''s. [Default: true]'\n type: boolean\n bpfEnabled:\n description: 'BPFEnabled, if enabled Felix will use the BPF dataplane.\n [Default: false]'\n type: boolean\n bpfEnforceRPF:\n description: 'BPFEnforceRPF enforce strict RPF on all host interfaces\n with BPF programs regardless of what is the per-interfaces or global\n setting. Possible values are Disabled, Strict or Loose. [Default:\n Loose]'\n pattern: ^(?i)(Disabled|Strict|Loose)?$\n type: string\n bpfExcludeCIDRsFromNAT:\n description: BPFExcludeCIDRsFromNAT is a list of CIDRs that are to\n be excluded from NAT resolution so that host can handle them. A\n typical usecase is node local DNS cache.\n items:\n type: string\n type: array\n bpfExtToServiceConnmark:\n description: 'BPFExtToServiceConnmark in BPF mode, control a 32bit\n mark that is set on connections from an external client to a local\n service. This mark allows us to control how packets of that connection\n are routed within the host and how is routing interpreted by RPF\n check. [Default: 0]'\n type: integer\n bpfExternalServiceMode:\n description: 'BPFExternalServiceMode in BPF mode, controls how connections\n from outside the cluster to services (node ports and cluster IPs)\n are forwarded to remote workloads. If set to \"Tunnel\" then both\n request and response traffic is tunneled to the remote node. If\n set to \"DSR\", the request traffic is tunneled but the response traffic\n is sent directly from the remote node. In \"DSR\" mode, the remote\n node appears to use the IP of the ingress node; this requires a\n permissive L2 network. [Default: Tunnel]'\n pattern: ^(?i)(Tunnel|DSR)?$\n type: string\n bpfForceTrackPacketsFromIfaces:\n description: 'BPFForceTrackPacketsFromIfaces in BPF mode, forces traffic\n from these interfaces to skip Calico''s iptables NOTRACK rule, allowing\n traffic from those interfaces to be tracked by Linux conntrack. Should\n only be used for interfaces that are not used for the Calico fabric. For\n example, a docker bridge device for non-Calico-networked containers.\n [Default: docker+]'\n items:\n type: string\n type: array\n bpfHostConntrackBypass:\n description: 'BPFHostConntrackBypass Controls whether to bypass Linux\n conntrack in BPF mode for workloads and services. [Default: true\n - bypass Linux conntrack]'\n type: boolean\n bpfHostNetworkedNATWithoutCTLB:\n description: 'BPFHostNetworkedNATWithoutCTLB when in BPF mode, controls\n whether Felix does a NAT without CTLB. This along with BPFConnectTimeLoadBalancing\n determines the CTLB behavior. [Default: Enabled]'\n enum:\n - Enabled\n - Disabled\n type: string\n bpfKubeProxyEndpointSlicesEnabled:\n description: BPFKubeProxyEndpointSlicesEnabled is deprecated and has\n no effect. BPF kube-proxy always accepts endpoint slices. This option\n will be removed in the next release.\n type: boolean\n bpfKubeProxyIptablesCleanupEnabled:\n description: 'BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF\n mode, Felix will proactively clean up the upstream Kubernetes kube-proxy''s\n iptables chains. Should only be enabled if kube-proxy is not running. [Default:\n true]'\n type: boolean\n bpfKubeProxyMinSyncPeriod:\n description: 'BPFKubeProxyMinSyncPeriod, in BPF mode, controls the\n minimum time between updates to the dataplane for Felix''s embedded\n kube-proxy. Lower values give reduced set-up latency. Higher values\n reduce Felix CPU usage by batching up more work. [Default: 1s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n bpfL3IfacePattern:\n description: BPFL3IfacePattern is a regular expression that allows\n to list tunnel devices like wireguard or vxlan (i.e., L3 devices)\n in addition to BPFDataIfacePattern. That is, tunnel interfaces not\n created by Calico, that Calico workload traffic flows over as well\n as any interfaces that handle incoming traffic to nodeports and\n services from outside the cluster.\n type: string\n bpfLogFilters:\n additionalProperties:\n type: string\n description: \"BPFLogFilters is a map of key=values where the value\n is a pcap filter expression and the key is an interface name with\n 'all' denoting all interfaces, 'weps' all workload endpoints and\n 'heps' all host endpoints. \\n When specified as an env var, it accepts\n a comma-separated list of key=values. [Default: unset - means all\n debug logs are emitted]\"\n type: object\n bpfLogLevel:\n description: 'BPFLogLevel controls the log level of the BPF programs\n when in BPF dataplane mode. One of \"Off\", \"Info\", or \"Debug\". The\n logs are emitted to the BPF trace pipe, accessible with the command\n `tc exec bpf debug`. [Default: Off].'\n pattern: ^(?i)(Off|Info|Debug)?$\n type: string\n bpfMapSizeConntrack:\n description: 'BPFMapSizeConntrack sets the size for the conntrack\n map. This map must be large enough to hold an entry for each active\n connection. Warning: changing the size of the conntrack map can\n cause disruption.'\n type: integer\n bpfMapSizeIPSets:\n description: BPFMapSizeIPSets sets the size for ipsets map. The IP\n sets map must be large enough to hold an entry for each endpoint\n matched by every selector in the source/destination matches in network\n policy. Selectors such as \"all()\" can result in large numbers of\n entries (one entry per endpoint in that case).\n type: integer\n bpfMapSizeIfState:\n description: BPFMapSizeIfState sets the size for ifstate map. The\n ifstate map must be large enough to hold an entry for each device\n (host + workloads) on a host.\n type: integer\n bpfMapSizeNATAffinity:\n type: integer\n bpfMapSizeNATBackend:\n description: BPFMapSizeNATBackend sets the size for nat back end map.\n This is the total number of endpoints. This is mostly more than\n the size of the number of services.\n type: integer\n bpfMapSizeNATFrontend:\n description: BPFMapSizeNATFrontend sets the size for nat front end\n map. FrontendMap should be large enough to hold an entry for each\n nodeport, external IP and each port in each service.\n type: integer\n bpfMapSizeRoute:\n description: BPFMapSizeRoute sets the size for the routes map. The\n routes map should be large enough to hold one entry per workload\n and a handful of entries per host (enough to cover its own IPs and\n tunnel IPs).\n type: integer\n bpfPSNATPorts:\n anyOf:\n - type: integer\n - type: string\n description: 'BPFPSNATPorts sets the range from which we randomly\n pick a port if there is a source port collision. This should be\n within the ephemeral range as defined by RFC 6056 (1024–65535) and\n preferably outside the ephemeral ranges used by common operating\n systems. Linux uses 32768–60999, while others mostly use the IANA\n defined range 49152–65535. It is not necessarily a problem if this\n range overlaps with the operating systems. Both ends of the range\n are inclusive. [Default: 20000:29999]'\n pattern: ^.*\n x-kubernetes-int-or-string: true\n bpfPolicyDebugEnabled:\n description: BPFPolicyDebugEnabled when true, Felix records detailed\n information about the BPF policy programs, which can be examined\n with the calico-bpf command-line tool.\n type: boolean\n bpfRedirectToPeer:\n description: 'BPFRedirectToPeer controls which whether it is allowed\n to forward straight to the peer side of the workload devices. It\n is allowed for any host L2 devices by default (L2Only), but it breaks\n TCP dump on the host side of workload device as it bypasses it on\n ingress. Value of Enabled also allows redirection from L3 host devices\n like IPIP tunnel or Wireguard directly to the peer side of the workload''s\n device. This makes redirection faster, however, it breaks tools\n like tcpdump on the peer side. Use Enabled with caution. [Default:\n L2Only]'\n type: string\n chainInsertMode:\n description: 'ChainInsertMode controls whether Felix hooks the kernel''s\n top-level iptables chains by inserting a rule at the top of the\n chain or by appending a rule at the bottom. insert is the safe default\n since it prevents Calico''s rules from being bypassed. If you switch\n to append mode, be sure that the other rules in the chains signal\n acceptance by falling through to the Calico rules, otherwise the\n Calico policy will be bypassed. [Default: insert]'\n pattern: ^(?i)(insert|append)?$\n type: string\n dataplaneDriver:\n description: DataplaneDriver filename of the external dataplane driver\n to use. Only used if UseInternalDataplaneDriver is set to false.\n type: string\n dataplaneWatchdogTimeout:\n description: \"DataplaneWatchdogTimeout is the readiness/liveness timeout\n used for Felix's (internal) dataplane driver. Increase this value\n if you experience spurious non-ready or non-live events when Felix\n is under heavy load. Decrease the value to get felix to report non-live\n or non-ready more quickly. [Default: 90s] \\n Deprecated: replaced\n by the generic HealthTimeoutOverrides.\"\n type: string\n debugDisableLogDropping:\n type: boolean\n debugHost:\n description: DebugHost is the host IP or hostname to bind the debug\n port to. Only used if DebugPort is set. [Default:localhost]\n type: string\n debugMemoryProfilePath:\n type: string\n debugPort:\n description: DebugPort if set, enables Felix's debug HTTP port, which\n allows memory and CPU profiles to be retrieved. The debug port\n is not secure, it should not be exposed to the internet.\n type: integer\n debugSimulateCalcGraphHangAfter:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n debugSimulateDataplaneApplyDelay:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n debugSimulateDataplaneHangAfter:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n defaultEndpointToHostAction:\n description: 'DefaultEndpointToHostAction controls what happens to\n traffic that goes from a workload endpoint to the host itself (after\n the traffic hits the endpoint egress policy). By default Calico\n blocks traffic from workload endpoints to the host itself with an\n iptables \"DROP\" action. If you want to allow some or all traffic\n from endpoint to host, set this parameter to RETURN or ACCEPT. Use\n RETURN if you have your own rules in the iptables \"INPUT\" chain;\n Calico will insert its rules at the top of that chain, then \"RETURN\"\n packets to the \"INPUT\" chain once it has completed processing workload\n endpoint egress policy. Use ACCEPT to unconditionally accept packets\n from workloads after processing workload endpoint egress policy.\n [Default: Drop]'\n pattern: ^(?i)(Drop|Accept|Return)?$\n type: string\n deviceRouteProtocol:\n description: This defines the route protocol added to programmed device\n routes, by default this will be RTPROT_BOOT when left blank.\n type: integer\n deviceRouteSourceAddress:\n description: This is the IPv4 source address to use on programmed\n device routes. By default the source address is left blank, leaving\n the kernel to choose the source address used.\n type: string\n deviceRouteSourceAddressIPv6:\n description: This is the IPv6 source address to use on programmed\n device routes. By default the source address is left blank, leaving\n the kernel to choose the source address used.\n type: string\n disableConntrackInvalidCheck:\n type: boolean\n endpointReportingDelay:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n endpointReportingEnabled:\n type: boolean\n endpointStatusPathPrefix:\n description: \"EndpointStatusPathPrefix is the path to the directory\n where endpoint status will be written. Endpoint status file reporting\n is disabled if field is left empty. \\n Chosen directory should match\n the directory used by the CNI for PodStartupDelay. [Default: \\\"\\\"]\"\n type: string\n externalNodesList:\n description: ExternalNodesCIDRList is a list of CIDR's of external-non-calico-nodes\n which may source tunnel traffic and have the tunneled traffic be\n accepted at calico nodes.\n items:\n type: string\n type: array\n failsafeInboundHostPorts:\n description: 'FailsafeInboundHostPorts is a list of PortProto struct\n objects including UDP/TCP/SCTP ports and CIDRs that Felix will allow\n incoming traffic to host endpoints on irrespective of the security\n policy. This is useful to avoid accidentally cutting off a host\n with incorrect configuration. For backwards compatibility, if the\n protocol is not specified, it defaults to \"tcp\". If a CIDR is not\n specified, it will allow traffic from all addresses. To disable\n all inbound host ports, use the value \"[]\". The default value allows\n ssh access, DHCP, BGP, etcd and the Kubernetes API. [Default: tcp:22,\n udp:68, tcp:179, tcp:2379, tcp:2380, tcp:5473, tcp:6443, tcp:6666,\n tcp:6667 ]'\n items:\n description: ProtoPort is combination of protocol, port, and CIDR.\n Protocol and port must be specified.\n properties:\n net:\n type: string\n port:\n type: integer\n protocol:\n type: string\n required:\n - port\n - protocol\n type: object\n type: array\n failsafeOutboundHostPorts:\n description: 'FailsafeOutboundHostPorts is a list of List of PortProto\n struct objects including UDP/TCP/SCTP ports and CIDRs that Felix\n will allow outgoing traffic from host endpoints to irrespective\n of the security policy. This is useful to avoid accidentally cutting\n off a host with incorrect configuration. For backwards compatibility,\n if the protocol is not specified, it defaults to \"tcp\". If a CIDR\n is not specified, it will allow traffic from all addresses. To disable\n all outbound host ports, use the value \"[]\". The default value opens\n etcd''s standard ports to ensure that Felix does not get cut off\n from etcd as well as allowing DHCP, DNS, BGP and the Kubernetes\n API. [Default: udp:53, udp:67, tcp:179, tcp:2379, tcp:2380, tcp:5473,\n tcp:6443, tcp:6666, tcp:6667 ]'\n items:\n description: ProtoPort is combination of protocol, port, and CIDR.\n Protocol and port must be specified.\n properties:\n net:\n type: string\n port:\n type: integer\n protocol:\n type: string\n required:\n - port\n - protocol\n type: object\n type: array\n featureDetectOverride:\n description: FeatureDetectOverride is used to override feature detection\n based on auto-detected platform capabilities. Values are specified\n in a comma separated list with no spaces, example; \"SNATFullyRandom=true,MASQFullyRandom=false,RestoreSupportsLock=\". \"true\"\n or \"false\" will force the feature, empty or omitted values are auto-detected.\n pattern: ^([a-zA-Z0-9-_]+=(true|false|),)*([a-zA-Z0-9-_]+=(true|false|))?$\n type: string\n featureGates:\n description: FeatureGates is used to enable or disable tech-preview\n Calico features. Values are specified in a comma separated list\n with no spaces, example; \"BPFConnectTimeLoadBalancingWorkaround=enabled,XyZ=false\".\n This is used to enable features that are not fully production ready.\n pattern: ^([a-zA-Z0-9-_]+=([^=]+),)*([a-zA-Z0-9-_]+=([^=]+))?$\n type: string\n floatingIPs:\n description: FloatingIPs configures whether or not Felix will program\n non-OpenStack floating IP addresses. (OpenStack-derived floating\n IPs are always programmed, regardless of this setting.)\n enum:\n - Enabled\n - Disabled\n type: string\n genericXDPEnabled:\n description: 'GenericXDPEnabled enables Generic XDP so network cards\n that don''t support XDP offload or driver modes can use XDP. This\n is not recommended since it doesn''t provide better performance\n than iptables. [Default: false]'\n type: boolean\n goGCThreshold:\n description: \"GoGCThreshold Sets the Go runtime's garbage collection\n threshold. I.e. the percentage that the heap is allowed to grow\n before garbage collection is triggered. In general, doubling the\n value halves the CPU time spent doing GC, but it also doubles peak\n GC memory overhead. A special value of -1 can be used to disable\n GC entirely; this should only be used in conjunction with the GoMemoryLimitMB\n setting. \\n This setting is overridden by the GOGC environment variable.\n \\n [Default: 40]\"\n type: integer\n goMaxProcs:\n description: \"GoMaxProcs sets the maximum number of CPUs that the\n Go runtime will use concurrently. A value of -1 means \\\"use the\n system default\\\"; typically the number of real CPUs on the system.\n \\n this setting is overridden by the GOMAXPROCS environment variable.\n \\n [Default: -1]\"\n type: integer\n goMemoryLimitMB:\n description: \"GoMemoryLimitMB sets a (soft) memory limit for the Go\n runtime in MB. The Go runtime will try to keep its memory usage\n under the limit by triggering GC as needed. To avoid thrashing,\n it will exceed the limit if GC starts to take more than 50% of the\n process's CPU time. A value of -1 disables the memory limit. \\n\n Note that the memory limit, if used, must be considerably less than\n any hard resource limit set at the container or pod level. This\n is because felix is not the only process that must run in the container\n or pod. \\n This setting is overridden by the GOMEMLIMIT environment\n variable. \\n [Default: -1]\"\n type: integer\n healthEnabled:\n type: boolean\n healthHost:\n type: string\n healthPort:\n type: integer\n healthTimeoutOverrides:\n description: HealthTimeoutOverrides allows the internal watchdog timeouts\n of individual subcomponents to be overridden. This is useful for\n working around \"false positive\" liveness timeouts that can occur\n in particularly stressful workloads or if CPU is constrained. For\n a list of active subcomponents, see Felix's logs.\n items:\n properties:\n name:\n type: string\n timeout:\n type: string\n required:\n - name\n - timeout\n type: object\n type: array\n interfaceExclude:\n description: 'InterfaceExclude is a comma-separated list of interfaces\n that Felix should exclude when monitoring for host endpoints. The\n default value ensures that Felix ignores Kubernetes'' IPVS dummy\n interface, which is used internally by kube-proxy. If you want to\n exclude multiple interface names using a single value, the list\n supports regular expressions. For regular expressions you must wrap\n the value with ''/''. For example having values ''/^kube/,veth1''\n will exclude all interfaces that begin with ''kube'' and also the\n interface ''veth1''. [Default: kube-ipvs0]'\n type: string\n interfacePrefix:\n description: 'InterfacePrefix is the interface name prefix that identifies\n workload endpoints and so distinguishes them from host endpoint\n interfaces. Note: in environments other than bare metal, the orchestrators\n configure this appropriately. For example our Kubernetes and Docker\n integrations set the ''cali'' value, and our OpenStack integration\n sets the ''tap'' value. [Default: cali]'\n type: string\n interfaceRefreshInterval:\n description: InterfaceRefreshInterval is the period at which Felix\n rescans local interfaces to verify their state. The rescan can be\n disabled by setting the interval to 0.\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n ipipEnabled:\n description: 'IPIPEnabled overrides whether Felix should configure\n an IPIP interface on the host. Optional as Felix determines this\n based on the existing IP pools. [Default: nil (unset)]'\n type: boolean\n ipipMTU:\n description: 'IPIPMTU is the MTU to set on the tunnel device. See\n Configuring MTU [Default: 1440]'\n type: integer\n ipsetsRefreshInterval:\n description: 'IpsetsRefreshInterval is the period at which Felix re-checks\n all iptables state to ensure that no other process has accidentally\n broken Calico''s rules. Set to 0 to disable iptables refresh. [Default:\n 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesBackend:\n description: IptablesBackend specifies which backend of iptables will\n be used. The default is Auto.\n pattern: ^(?i)(Auto|FelixConfiguration|FelixConfigurationList|Legacy|NFT)?$\n type: string\n iptablesFilterAllowAction:\n pattern: ^(?i)(Accept|Return)?$\n type: string\n iptablesFilterDenyAction:\n description: IptablesFilterDenyAction controls what happens to traffic\n that is denied by network policy. By default Calico blocks traffic\n with an iptables \"DROP\" action. If you want to use \"REJECT\" action\n instead you can configure it in here.\n pattern: ^(?i)(Drop|Reject)?$\n type: string\n iptablesLockFilePath:\n description: 'IptablesLockFilePath is the location of the iptables\n lock file. You may need to change this if the lock file is not in\n its standard location (for example if you have mapped it into Felix''s\n container at a different path). [Default: /run/xtables.lock]'\n type: string\n iptablesLockProbeInterval:\n description: 'IptablesLockProbeInterval is the time that Felix will\n wait between attempts to acquire the iptables lock if it is not\n available. Lower values make Felix more responsive when the lock\n is contended, but use more CPU. [Default: 50ms]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesLockTimeout:\n description: 'IptablesLockTimeout is the time that Felix will wait\n for the iptables lock, or 0, to disable. To use this feature, Felix\n must share the iptables lock file with all other processes that\n also take the lock. When running Felix inside a container, this\n requires the /run directory of the host to be mounted into the calico/node\n or calico/felix container. [Default: 0s disabled]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesMangleAllowAction:\n pattern: ^(?i)(Accept|Return)?$\n type: string\n iptablesMarkMask:\n description: 'IptablesMarkMask is the mask that Felix selects its\n IPTables Mark bits from. Should be a 32 bit hexadecimal number with\n at least 8 bits set, none of which clash with any other mark bits\n in use on the system. [Default: 0xff000000]'\n format: int32\n type: integer\n iptablesNATOutgoingInterfaceFilter:\n type: string\n iptablesPostWriteCheckInterval:\n description: 'IptablesPostWriteCheckInterval is the period after Felix\n has done a write to the dataplane that it schedules an extra read\n back in order to check the write was not clobbered by another process.\n This should only occur if another application on the system doesn''t\n respect the iptables lock. [Default: 1s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n iptablesRefreshInterval:\n description: 'IptablesRefreshInterval is the period at which Felix\n re-checks the IP sets in the dataplane to ensure that no other process\n has accidentally broken Calico''s rules. Set to 0 to disable IP\n sets refresh. Note: the default for this value is lower than the\n other refresh intervals as a workaround for a Linux kernel bug that\n was fixed in kernel version 4.11. If you are using v4.11 or greater\n you may want to set this to, a higher value to reduce Felix CPU\n usage. [Default: 10s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n ipv6Support:\n description: IPv6Support controls whether Felix enables support for\n IPv6 (if supported by the in-use dataplane).\n type: boolean\n kubeNodePortRanges:\n description: 'KubeNodePortRanges holds list of port ranges used for\n service node ports. Only used if felix detects kube-proxy running\n in ipvs mode. Felix uses these ranges to separate host and workload\n traffic. [Default: 30000:32767].'\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n logDebugFilenameRegex:\n description: LogDebugFilenameRegex controls which source code files\n have their Debug log output included in the logs. Only logs from\n files with names that match the given regular expression are included. The\n filter only applies to Debug level logs.\n type: string\n logFilePath:\n description: 'LogFilePath is the full path to the Felix log. Set to\n none to disable file logging. [Default: /var/log/calico/felix.log]'\n type: string\n logPrefix:\n description: 'LogPrefix is the log prefix that Felix uses when rendering\n LOG rules. [Default: calico-packet]'\n type: string\n logSeverityFile:\n description: 'LogSeverityFile is the log severity above which logs\n are sent to the log file. [Default: Info]'\n pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$\n type: string\n logSeverityScreen:\n description: 'LogSeverityScreen is the log severity above which logs\n are sent to the stdout. [Default: Info]'\n pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$\n type: string\n logSeveritySys:\n description: 'LogSeveritySys is the log severity above which logs\n are sent to the syslog. Set to None for no logging to syslog. [Default:\n Info]'\n pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$\n type: string\n maxIpsetSize:\n description: MaxIpsetSize is the maximum number of IP addresses that\n can be stored in an IP set. Not applicable if using the nftables\n backend.\n type: integer\n metadataAddr:\n description: 'MetadataAddr is the IP address or domain name of the\n server that can answer VM queries for cloud-init metadata. In OpenStack,\n this corresponds to the machine running nova-api (or in Ubuntu,\n nova-api-metadata). A value of none (case-insensitive) means that\n Felix should not set up any NAT rule for the metadata path. [Default:\n 127.0.0.1]'\n type: string\n metadataPort:\n description: 'MetadataPort is the port of the metadata server. This,\n combined with global.MetadataAddr (if not ''None''), is used to\n set up a NAT rule, from 169.254.169.254:80 to MetadataAddr:MetadataPort.\n In most cases this should not need to be changed [Default: 8775].'\n type: integer\n mtuIfacePattern:\n description: MTUIfacePattern is a regular expression that controls\n which interfaces Felix should scan in order to calculate the host's\n MTU. This should not match workload interfaces (usually named cali...).\n type: string\n natOutgoingAddress:\n description: NATOutgoingAddress specifies an address to use when performing\n source NAT for traffic in a natOutgoing pool that is leaving the\n network. By default the address used is an address on the interface\n the traffic is leaving on (ie it uses the iptables MASQUERADE target)\n type: string\n natPortRange:\n anyOf:\n - type: integer\n - type: string\n description: NATPortRange specifies the range of ports that is used\n for port mapping when doing outgoing NAT. When unset the default\n behavior of the network stack is used.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n netlinkTimeout:\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n nftablesFilterAllowAction:\n pattern: ^(?i)(Accept|Return)?$\n type: string\n nftablesFilterDenyAction:\n description: FilterDenyAction controls what happens to traffic that\n is denied by network policy. By default Calico blocks traffic with\n a \"drop\" action. If you want to use a \"reject\" action instead you\n can configure it here.\n pattern: ^(?i)(Drop|Reject)?$\n type: string\n nftablesMangleAllowAction:\n pattern: ^(?i)(Accept|Return)?$\n type: string\n nftablesMarkMask:\n description: 'MarkMask is the mask that Felix selects its nftables\n Mark bits from. Should be a 32 bit hexadecimal number with at least\n 8 bits set, none of which clash with any other mark bits in use\n on the system. [Default: 0xffff0000]'\n format: int32\n type: integer\n nftablesMode:\n description: 'NFTablesMode configures nftables support in Felix. [Default:\n Disabled]'\n type: string\n nftablesRefreshInterval:\n description: 'NftablesRefreshInterval controls the interval at which\n Felix periodically refreshes the nftables rules. [Default: 90s]'\n type: string\n openstackRegion:\n description: 'OpenstackRegion is the name of the region that a particular\n Felix belongs to. In a multi-region Calico/OpenStack deployment,\n this must be configured somehow for each Felix (here in the datamodel,\n or in felix.cfg or the environment on each compute node), and must\n match the [calico] openstack_region value configured in neutron.conf\n on each node. [Default: Empty]'\n type: string\n policySyncPathPrefix:\n description: 'PolicySyncPathPrefix is used to by Felix to communicate\n policy changes to external services, like Application layer policy.\n [Default: Empty]'\n type: string\n prometheusGoMetricsEnabled:\n description: 'PrometheusGoMetricsEnabled disables Go runtime metrics\n collection, which the Prometheus client does by default, when set\n to false. This reduces the number of metrics reported, reducing\n Prometheus load. [Default: true]'\n type: boolean\n prometheusMetricsEnabled:\n description: 'PrometheusMetricsEnabled enables the Prometheus metrics\n server in Felix if set to true. [Default: false]'\n type: boolean\n prometheusMetricsHost:\n description: 'PrometheusMetricsHost is the host that the Prometheus\n metrics server should bind to. [Default: empty]'\n type: string\n prometheusMetricsPort:\n description: 'PrometheusMetricsPort is the TCP port that the Prometheus\n metrics server should bind to. [Default: 9091]'\n type: integer\n prometheusProcessMetricsEnabled:\n description: 'PrometheusProcessMetricsEnabled disables process metrics\n collection, which the Prometheus client does by default, when set\n to false. This reduces the number of metrics reported, reducing\n Prometheus load. [Default: true]'\n type: boolean\n prometheusWireGuardMetricsEnabled:\n description: 'PrometheusWireGuardMetricsEnabled disables wireguard\n metrics collection, which the Prometheus client does by default,\n when set to false. This reduces the number of metrics reported,\n reducing Prometheus load. [Default: true]'\n type: boolean\n removeExternalRoutes:\n description: Whether or not to remove device routes that have not\n been programmed by Felix. Disabling this will allow external applications\n to also add device routes. This is enabled by default which means\n we will remove externally added routes.\n type: boolean\n reportingInterval:\n description: 'ReportingInterval is the interval at which Felix reports\n its status into the datastore or 0 to disable. Must be non-zero\n in OpenStack deployments. [Default: 30s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n reportingTTL:\n description: 'ReportingTTL is the time-to-live setting for process-wide\n status reports. [Default: 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n routeRefreshInterval:\n description: 'RouteRefreshInterval is the period at which Felix re-checks\n the routes in the dataplane to ensure that no other process has\n accidentally broken Calico''s rules. Set to 0 to disable route refresh.\n [Default: 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n routeSource:\n description: 'RouteSource configures where Felix gets its routing\n information. - WorkloadIPs: use workload endpoints to construct\n routes. - CalicoIPAM: the default - use IPAM data to construct routes.'\n pattern: ^(?i)(WorkloadIPs|CalicoIPAM)?$\n type: string\n routeSyncDisabled:\n description: RouteSyncDisabled will disable all operations performed\n on the route table. Set to true to run in network-policy mode only.\n type: boolean\n routeTableRange:\n description: Deprecated in favor of RouteTableRanges. Calico programs\n additional Linux route tables for various purposes. RouteTableRange\n specifies the indices of the route tables that Calico should use.\n properties:\n max:\n type: integer\n min:\n type: integer\n required:\n - max\n - min\n type: object\n routeTableRanges:\n description: Calico programs additional Linux route tables for various\n purposes. RouteTableRanges specifies a set of table index ranges\n that Calico should use. Deprecates`RouteTableRange`, overrides `RouteTableRange`.\n items:\n properties:\n max:\n type: integer\n min:\n type: integer\n required:\n - max\n - min\n type: object\n type: array\n serviceLoopPrevention:\n description: 'When service IP advertisement is enabled, prevent routing\n loops to service IPs that are not in use, by dropping or rejecting\n packets that do not get DNAT''d by kube-proxy. Unless set to \"Disabled\",\n in which case such routing loops continue to be allowed. [Default:\n Drop]'\n pattern: ^(?i)(Drop|Reject|Disabled)?$\n type: string\n sidecarAccelerationEnabled:\n description: 'SidecarAccelerationEnabled enables experimental sidecar\n acceleration [Default: false]'\n type: boolean\n usageReportingEnabled:\n description: 'UsageReportingEnabled reports anonymous Calico version\n number and cluster size to projectcalico.org. Logs warnings returned\n by the usage server. For example, if a significant security vulnerability\n has been discovered in the version of Calico being used. [Default:\n true]'\n type: boolean\n usageReportingInitialDelay:\n description: 'UsageReportingInitialDelay controls the minimum delay\n before Felix makes a report. [Default: 300s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n usageReportingInterval:\n description: 'UsageReportingInterval controls the interval at which\n Felix makes reports. [Default: 86400s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n useInternalDataplaneDriver:\n description: UseInternalDataplaneDriver, if true, Felix will use its\n internal dataplane programming logic. If false, it will launch\n an external dataplane driver and communicate with it over protobuf.\n type: boolean\n vxlanEnabled:\n description: 'VXLANEnabled overrides whether Felix should create the\n VXLAN tunnel device for IPv4 VXLAN networking. Optional as Felix\n determines this based on the existing IP pools. [Default: nil (unset)]'\n type: boolean\n vxlanMTU:\n description: 'VXLANMTU is the MTU to set on the IPv4 VXLAN tunnel\n device. See Configuring MTU [Default: 1410]'\n type: integer\n vxlanMTUV6:\n description: 'VXLANMTUV6 is the MTU to set on the IPv6 VXLAN tunnel\n device. See Configuring MTU [Default: 1390]'\n type: integer\n vxlanPort:\n type: integer\n vxlanVNI:\n type: integer\n windowsManageFirewallRules:\n description: 'WindowsManageFirewallRules configures whether or not\n Felix will program Windows Firewall rules. (to allow inbound access\n to its own metrics ports) [Default: Disabled]'\n enum:\n - Enabled\n - Disabled\n type: string\n wireguardEnabled:\n description: 'WireguardEnabled controls whether Wireguard is enabled\n for IPv4 (encapsulating IPv4 traffic over an IPv4 underlay network).\n [Default: false]'\n type: boolean\n wireguardEnabledV6:\n description: 'WireguardEnabledV6 controls whether Wireguard is enabled\n for IPv6 (encapsulating IPv6 traffic over an IPv6 underlay network).\n [Default: false]'\n type: boolean\n wireguardHostEncryptionEnabled:\n description: 'WireguardHostEncryptionEnabled controls whether Wireguard\n host-to-host encryption is enabled. [Default: false]'\n type: boolean\n wireguardInterfaceName:\n description: 'WireguardInterfaceName specifies the name to use for\n the IPv4 Wireguard interface. [Default: wireguard.cali]'\n type: string\n wireguardInterfaceNameV6:\n description: 'WireguardInterfaceNameV6 specifies the name to use for\n the IPv6 Wireguard interface. [Default: wg-v6.cali]'\n type: string\n wireguardKeepAlive:\n description: 'WireguardKeepAlive controls Wireguard PersistentKeepalive\n option. Set 0 to disable. [Default: 0]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n wireguardListeningPort:\n description: 'WireguardListeningPort controls the listening port used\n by IPv4 Wireguard. [Default: 51820]'\n type: integer\n wireguardListeningPortV6:\n description: 'WireguardListeningPortV6 controls the listening port\n used by IPv6 Wireguard. [Default: 51821]'\n type: integer\n wireguardMTU:\n description: 'WireguardMTU controls the MTU on the IPv4 Wireguard\n interface. See Configuring MTU [Default: 1440]'\n type: integer\n wireguardMTUV6:\n description: 'WireguardMTUV6 controls the MTU on the IPv6 Wireguard\n interface. See Configuring MTU [Default: 1420]'\n type: integer\n wireguardRoutingRulePriority:\n description: 'WireguardRoutingRulePriority controls the priority value\n to use for the Wireguard routing rule. [Default: 99]'\n type: integer\n workloadSourceSpoofing:\n description: WorkloadSourceSpoofing controls whether pods can use\n the allowedSourcePrefixes annotation to send traffic with a source\n IP address that is not theirs. This is disabled by default. When\n set to \"Any\", pods can request any prefix.\n pattern: ^(?i)(Disabled|Any)?$\n type: string\n xdpEnabled:\n description: 'XDPEnabled enables XDP acceleration for suitable untracked\n incoming deny rules. [Default: true]'\n type: boolean\n xdpRefreshInterval:\n description: 'XDPRefreshInterval is the period at which Felix re-checks\n all XDP state to ensure that no other process has accidentally broken\n Calico''s BPF maps or attached programs. Set to 0 to disable XDP\n refresh. [Default: 90s]'\n pattern: ^([0-9]+(\\\\.[0-9]+)?(ms|s|m|h))*$\n type: string\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" + globalnetworkpolicies = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: globalnetworkpolicies.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: GlobalNetworkPolicy\n listKind: GlobalNetworkPolicyList\n plural: globalnetworkpolicies\n singular: globalnetworkpolicy\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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 properties:\n applyOnForward:\n description: ApplyOnForward indicates to apply the rules in this policy\n on forward traffic.\n type: boolean\n doNotTrack:\n description: DoNotTrack indicates whether packets matched by the rules\n in this policy should go through the data plane's connection tracking,\n such as Linux conntrack. If True, the rules in this policy are\n applied before any data plane connection tracking, and packets allowed\n by this policy are marked as not to be tracked.\n type: boolean\n egress:\n description: The ordered set of egress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n ingress:\n description: The ordered set of ingress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n namespaceSelector:\n description: NamespaceSelector is an optional field for an expression\n used to select a pod based on namespaces.\n type: string\n order:\n description: Order is an optional field that specifies the order in\n which the policy is applied. Policies with higher \"order\" are applied\n after those with lower order within the same tier. If the order\n is omitted, it may be considered to be \"infinite\" - i.e. the policy\n will be applied last. Policies with identical order will be applied\n in alphanumerical order based on the Policy \"Name\" within the tier.\n type: number\n performanceHints:\n description: \"PerformanceHints contains a list of hints to Calico's\n policy engine to help process the policy more efficiently. Hints\n never change the enforcement behaviour of the policy. \\n Currently,\n the only available hint is \\\"AssumeNeededOnEveryNode\\\". When that\n hint is set on a policy, Felix will act as if the policy matches\n a local endpoint even if it does not. This is useful for \\\"preloading\\\"\n any large static policies that are known to be used on every node.\n If the policy is _not_ used on a particular node then the work done\n to preload the policy (and to maintain it) is wasted.\"\n items:\n type: string\n type: array\n preDNAT:\n description: PreDNAT indicates to apply the rules in this policy before\n any DNAT.\n type: boolean\n selector:\n description: \"The selector is an expression used to pick out the endpoints\n that the policy should be applied to. \\n Selector expressions follow\n this syntax: \\n \\tlabel == \\\"string_literal\\\" -> comparison, e.g.\n my_label == \\\"foo bar\\\" \\tlabel != \\\"string_literal\\\" -> not\n equal; also matches if label is not present \\tlabel in { \\\"a\\\",\n \\\"b\\\", \\\"c\\\", ... } -> true if the value of label X is one of\n \\\"a\\\", \\\"b\\\", \\\"c\\\" \\tlabel not in { \\\"a\\\", \\\"b\\\", \\\"c\\\", ... }\n \\ -> true if the value of label X is not one of \\\"a\\\", \\\"b\\\", \\\"c\\\"\n \\thas(label_name) -> True if that label is present \\t! expr ->\n negation of expr \\texpr && expr -> Short-circuit and \\texpr ||\n expr -> Short-circuit or \\t( expr ) -> parens for grouping \\tall()\n or the empty selector -> matches all endpoints. \\n Label names are\n allowed to contain alphanumerics, -, _ and /. String literals are\n more permissive but they do not support escape characters. \\n Examples\n (with made-up labels): \\n \\ttype == \\\"webserver\\\" && deployment\n == \\\"prod\\\" \\ttype in {\\\"frontend\\\", \\\"backend\\\"} \\tdeployment !=\n \\\"dev\\\" \\t! has(label_name)\"\n type: string\n serviceAccountSelector:\n description: ServiceAccountSelector is an optional field for an expression\n used to select a pod based on service accounts.\n type: string\n tier:\n description: The name of the tier that this policy belongs to. If\n this is omitted, the default tier (name is \"default\") is assumed. The\n specified tier must exist in order to create security policies within\n the tier, the \"default\" tier is created automatically if it does\n not exist, this means for deployments requiring only a single Tier,\n the tier name may be omitted on all policy management requests.\n type: string\n types:\n description: \"Types indicates whether this policy applies to ingress,\n or to egress, or to both. When not explicitly specified (and so\n the value on creation is empty or nil), Calico defaults Types according\n to what Ingress and Egress rules are present in the policy. The\n default is: \\n - [ PolicyTypeIngress ], if there are no Egress rules\n (including the case where there are also no Ingress rules) \\n\n - [ PolicyTypeEgress ], if there are Egress rules but no Ingress\n rules \\n - [ PolicyTypeIngress, PolicyTypeEgress ], if there are\n both Ingress and Egress rules. \\n When the policy is read back again,\n Types will always be one of these values, never empty or nil.\"\n items:\n description: PolicyType enumerates the possible values of the PolicySpec\n Types field.\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" globalnetworksets = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: globalnetworksets.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: GlobalNetworkSet\n listKind: GlobalNetworkSetList\n plural: globalnetworksets\n singular: globalnetworkset\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n description: GlobalNetworkSet contains a set of arbitrary IP sub-networks/CIDRs\n that share labels to allow rules to refer to them via selectors. The labels\n of GlobalNetworkSet are not namespaced.\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: GlobalNetworkSetSpec contains the specification for a NetworkSet\n resource.\n properties:\n nets:\n description: The list of IP networks that belong to this set.\n items:\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" hostendpoints = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: hostendpoints.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: HostEndpoint\n listKind: HostEndpointList\n plural: hostendpoints\n singular: hostendpoint\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: HostEndpointSpec contains the specification for a HostEndpoint\n resource.\n properties:\n expectedIPs:\n description: \"The expected IP addresses (IPv4 and IPv6) of the endpoint.\n If \\\"InterfaceName\\\" is not present, Calico will look for an interface\n matching any of the IPs in the list and apply policy to that. Note:\n \\tWhen using the selector match criteria in an ingress or egress\n security Policy \\tor Profile, Calico converts the selector into\n a set of IP addresses. For host \\tendpoints, the ExpectedIPs field\n is used for that purpose. (If only the interface \\tname is specified,\n Calico does not learn the IPs of the interface for use in match\n \\tcriteria.)\"\n items:\n type: string\n type: array\n interfaceName:\n description: \"Either \\\"*\\\", or the name of a specific Linux interface\n to apply policy to; or empty. \\\"*\\\" indicates that this HostEndpoint\n governs all traffic to, from or through the default network namespace\n of the host named by the \\\"Node\\\" field; entering and leaving that\n namespace via any interface, including those from/to non-host-networked\n local workloads. \\n If InterfaceName is not \\\"*\\\", this HostEndpoint\n only governs traffic that enters or leaves the host through the\n specific interface named by InterfaceName, or - when InterfaceName\n is empty - through the specific interface that has one of the IPs\n in ExpectedIPs. Therefore, when InterfaceName is empty, at least\n one expected IP must be specified. Only external interfaces (such\n as \\\"eth0\\\") are supported here; it isn't possible for a HostEndpoint\n to protect traffic through a specific local workload interface.\n \\n Note: Only some kinds of policy are implemented for \\\"*\\\" HostEndpoints;\n initially just pre-DNAT policy. Please check Calico documentation\n for the latest position.\"\n type: string\n node:\n description: The node name identifying the Calico node instance.\n type: string\n ports:\n description: Ports contains the endpoint's named ports, which may\n be referenced in security policy rules.\n items:\n properties:\n name:\n type: string\n port:\n type: integer\n protocol:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n required:\n - name\n - port\n - protocol\n type: object\n type: array\n profiles:\n description: A list of identifiers of security Profile objects that\n apply to this endpoint. Each profile is applied in the order that\n they appear in this list. Profile rules are applied after the selector-based\n security policy.\n items:\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" ipamblocks = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: ipamblocks.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: IPAMBlock\n listKind: IPAMBlockList\n plural: ipamblocks\n singular: ipamblock\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: IPAMBlockSpec contains the specification for an IPAMBlock\n resource.\n properties:\n affinity:\n description: Affinity of the block, if this block has one. If set,\n it will be of the form \"host:\". If not set, this block\n is not affine to a host.\n type: string\n allocations:\n description: Array of allocations in-use within this block. nil entries\n mean the allocation is free. For non-nil entries at index i, the\n index is the ordinal of the allocation within this block and the\n value is the index of the associated attributes in the Attributes\n array.\n items:\n type: integer\n # TODO: This nullable is manually added in. We should update controller-gen\n # to handle []*int properly itself.\n nullable: true\n type: array\n attributes:\n description: Attributes is an array of arbitrary metadata associated\n with allocations in the block. To find attributes for a given allocation,\n use the value of the allocation's entry in the Allocations array\n as the index of the element in this array.\n items:\n properties:\n handle_id:\n type: string\n secondary:\n additionalProperties:\n type: string\n type: object\n type: object\n type: array\n cidr:\n description: The block's CIDR.\n type: string\n deleted:\n description: Deleted is an internal boolean used to workaround a limitation\n in the Kubernetes API whereby deletion will not return a conflict\n error if the block has been updated. It should not be set manually.\n type: boolean\n sequenceNumber:\n default: 0\n description: We store a sequence number that is updated each time\n the block is written. Each allocation will also store the sequence\n number of the block at the time of its creation. When releasing\n an IP, passing the sequence number associated with the allocation\n allows us to protect against a race condition and ensure the IP\n hasn't been released and re-allocated since the release request.\n format: int64\n type: integer\n sequenceNumberForAllocation:\n additionalProperties:\n format: int64\n type: integer\n description: Map of allocated ordinal within the block to sequence\n number of the block at the time of allocation. Kubernetes does not\n allow numerical keys for maps, so the key is cast to a string.\n type: object\n strictAffinity:\n description: StrictAffinity on the IPAMBlock is deprecated and no\n longer used by the code. Use IPAMConfig StrictAffinity instead.\n type: boolean\n unallocated:\n description: Unallocated is an ordered list of allocations which are\n free in the block.\n items:\n type: integer\n type: array\n required:\n - allocations\n - attributes\n - cidr\n - strictAffinity\n - unallocated\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" @@ -33,6 +33,7 @@ const ( ippools = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: ippools.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: IPPool\n listKind: IPPoolList\n plural: ippools\n singular: ippool\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: IPPoolSpec contains the specification for an IPPool resource.\n properties:\n allowedUses:\n description: AllowedUse controls what the IP pool will be used for. If\n not specified or empty, defaults to [\"Tunnel\", \"Workload\"] for back-compatibility\n items:\n type: string\n type: array\n blockSize:\n description: The block size to use for IP address assignments from\n this pool. Defaults to 26 for IPv4 and 122 for IPv6.\n type: integer\n cidr:\n description: The pool CIDR.\n type: string\n disableBGPExport:\n description: 'Disable exporting routes from this IP Pool''s CIDR over\n BGP. [Default: false]'\n type: boolean\n disabled:\n description: When disabled is true, Calico IPAM will not assign addresses\n from this pool.\n type: boolean\n ipip:\n description: 'Deprecated: this field is only used for APIv1 backwards\n compatibility. Setting this field is not allowed, this field is\n for internal use only.'\n properties:\n enabled:\n description: When enabled is true, ipip tunneling will be used\n to deliver packets to destinations within this pool.\n type: boolean\n mode:\n description: The IPIP mode. This can be one of \"always\" or \"cross-subnet\". A\n mode of \"always\" will also use IPIP tunneling for routing to\n destination IP addresses within this pool. A mode of \"cross-subnet\"\n will only use IPIP tunneling when the destination node is on\n a different subnet to the originating node. The default value\n (if not specified) is \"always\".\n type: string\n type: object\n ipipMode:\n description: Contains configuration for IPIP tunneling for this pool.\n If not specified, then this is defaulted to \"Never\" (i.e. IPIP tunneling\n is disabled).\n type: string\n nat-outgoing:\n description: 'Deprecated: this field is only used for APIv1 backwards\n compatibility. Setting this field is not allowed, this field is\n for internal use only.'\n type: boolean\n natOutgoing:\n description: When natOutgoing is true, packets sent from Calico networked\n containers in this pool to destinations outside of this pool will\n be masqueraded.\n type: boolean\n nodeSelector:\n description: Allows IPPool to allocate for a specific node by label\n selector.\n type: string\n vxlanMode:\n description: Contains configuration for VXLAN tunneling for this pool.\n If not specified, then this is defaulted to \"Never\" (i.e. VXLAN\n tunneling is disabled).\n type: string\n required:\n - cidr\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" ipreservations = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n annotations:\n controller-gen.kubebuilder.io/version: (devel)\n creationTimestamp: null\n name: ipreservations.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: IPReservation\n listKind: IPReservationList\n plural: ipreservations\n singular: ipreservation\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: IPReservationSpec contains the specification for an IPReservation\n resource.\n properties:\n reservedCIDRs:\n description: ReservedCIDRs is a list of CIDRs and/or IP addresses\n that Calico IPAM will exclude from new allocations.\n items:\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" kubecontrollersconfigurations = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: kubecontrollersconfigurations.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: KubeControllersConfiguration\n listKind: KubeControllersConfigurationList\n plural: kubecontrollersconfigurations\n singular: kubecontrollersconfiguration\n preserveUnknownFields: false\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: KubeControllersConfigurationSpec contains the values of the\n Kubernetes controllers configuration.\n properties:\n controllers:\n description: Controllers enables and configures individual Kubernetes\n controllers\n properties:\n namespace:\n description: Namespace enables and configures the namespace controller.\n Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform reconciliation\n with the Calico datastore. [Default: 5m]'\n type: string\n type: object\n node:\n description: Node enables and configures the node controller.\n Enabled by default, set to nil to disable.\n properties:\n hostEndpoint:\n description: HostEndpoint controls syncing nodes to host endpoints.\n Disabled by default, set to nil to disable.\n properties:\n autoCreate:\n description: 'AutoCreate enables automatic creation of\n host endpoints for every node. [Default: Disabled]'\n type: string\n type: object\n leakGracePeriod:\n description: 'LeakGracePeriod is the period used by the controller\n to determine if an IP address has been leaked. Set to 0\n to disable IP garbage collection. [Default: 15m]'\n type: string\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform reconciliation\n with the Calico datastore. [Default: 5m]'\n type: string\n syncLabels:\n description: 'SyncLabels controls whether to copy Kubernetes\n node labels to Calico nodes. [Default: Enabled]'\n type: string\n type: object\n policy:\n description: Policy enables and configures the policy controller.\n Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform reconciliation\n with the Calico datastore. [Default: 5m]'\n type: string\n type: object\n serviceAccount:\n description: ServiceAccount enables and configures the service\n account controller. Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform reconciliation\n with the Calico datastore. [Default: 5m]'\n type: string\n type: object\n workloadEndpoint:\n description: WorkloadEndpoint enables and configures the workload\n endpoint controller. Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform reconciliation\n with the Calico datastore. [Default: 5m]'\n type: string\n type: object\n type: object\n debugProfilePort:\n description: DebugProfilePort configures the port to serve memory\n and cpu profiles on. If not specified, profiling is disabled.\n format: int32\n type: integer\n etcdV3CompactionPeriod:\n description: 'EtcdV3CompactionPeriod is the period between etcdv3\n compaction requests. Set to 0 to disable. [Default: 10m]'\n type: string\n healthChecks:\n description: 'HealthChecks enables or disables support for health\n checks [Default: Enabled]'\n type: string\n logSeverityScreen:\n description: 'LogSeverityScreen is the log severity above which logs\n are sent to the stdout. [Default: Info]'\n type: string\n prometheusMetricsPort:\n description: 'PrometheusMetricsPort is the TCP port that the Prometheus\n metrics server should bind to. Set to 0 to disable. [Default: 9094]'\n type: integer\n required:\n - controllers\n type: object\n status:\n description: KubeControllersConfigurationStatus represents the status\n of the configuration. It's useful for admins to be able to see the actual\n config that was applied, which can be modified by environment variables\n on the kube-controllers process.\n properties:\n environmentVars:\n additionalProperties:\n type: string\n description: EnvironmentVars contains the environment variables on\n the kube-controllers that influenced the RunningConfig.\n type: object\n runningConfig:\n description: RunningConfig contains the effective config that is running\n in the kube-controllers pod, after merging the API resource with\n any environment variables.\n properties:\n controllers:\n description: Controllers enables and configures individual Kubernetes\n controllers\n properties:\n namespace:\n description: Namespace enables and configures the namespace\n controller. Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform\n reconciliation with the Calico datastore. [Default:\n 5m]'\n type: string\n type: object\n node:\n description: Node enables and configures the node controller.\n Enabled by default, set to nil to disable.\n properties:\n hostEndpoint:\n description: HostEndpoint controls syncing nodes to host\n endpoints. Disabled by default, set to nil to disable.\n properties:\n autoCreate:\n description: 'AutoCreate enables automatic creation\n of host endpoints for every node. [Default: Disabled]'\n type: string\n type: object\n leakGracePeriod:\n description: 'LeakGracePeriod is the period used by the\n controller to determine if an IP address has been leaked.\n Set to 0 to disable IP garbage collection. [Default:\n 15m]'\n type: string\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform\n reconciliation with the Calico datastore. [Default:\n 5m]'\n type: string\n syncLabels:\n description: 'SyncLabels controls whether to copy Kubernetes\n node labels to Calico nodes. [Default: Enabled]'\n type: string\n type: object\n policy:\n description: Policy enables and configures the policy controller.\n Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform\n reconciliation with the Calico datastore. [Default:\n 5m]'\n type: string\n type: object\n serviceAccount:\n description: ServiceAccount enables and configures the service\n account controller. Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform\n reconciliation with the Calico datastore. [Default:\n 5m]'\n type: string\n type: object\n workloadEndpoint:\n description: WorkloadEndpoint enables and configures the workload\n endpoint controller. Enabled by default, set to nil to disable.\n properties:\n reconcilerPeriod:\n description: 'ReconcilerPeriod is the period to perform\n reconciliation with the Calico datastore. [Default:\n 5m]'\n type: string\n type: object\n type: object\n debugProfilePort:\n description: DebugProfilePort configures the port to serve memory\n and cpu profiles on. If not specified, profiling is disabled.\n format: int32\n type: integer\n etcdV3CompactionPeriod:\n description: 'EtcdV3CompactionPeriod is the period between etcdv3\n compaction requests. Set to 0 to disable. [Default: 10m]'\n type: string\n healthChecks:\n description: 'HealthChecks enables or disables support for health\n checks [Default: Enabled]'\n type: string\n logSeverityScreen:\n description: 'LogSeverityScreen is the log severity above which\n logs are sent to the stdout. [Default: Info]'\n type: string\n prometheusMetricsPort:\n description: 'PrometheusMetricsPort is the TCP port that the Prometheus\n metrics server should bind to. Set to 0 to disable. [Default:\n 9094]'\n type: integer\n required:\n - controllers\n type: object\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" - networkpolicies = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: networkpolicies.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: NetworkPolicy\n listKind: NetworkPolicyList\n plural: networkpolicies\n singular: networkpolicy\n preserveUnknownFields: false\n scope: Namespaced\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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 properties:\n egress:\n description: The ordered set of egress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n ingress:\n description: The ordered set of ingress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n order:\n description: Order is an optional field that specifies the order in\n which the policy is applied. Policies with higher \"order\" are applied\n after those with lower order. If the order is omitted, it may be\n considered to be \"infinite\" - i.e. the policy will be applied last. Policies\n with identical order will be applied in alphanumerical order based\n on the Policy \"Name\".\n type: number\n performanceHints:\n description: \"PerformanceHints contains a list of hints to Calico's\n policy engine to help process the policy more efficiently. Hints\n never change the enforcement behaviour of the policy. \\n Currently,\n the only available hint is \\\"AssumeNeededOnEveryNode\\\". When that\n hint is set on a policy, Felix will act as if the policy matches\n a local endpoint even if it does not. This is useful for \\\"preloading\\\"\n any large static policies that are known to be used on every node.\n If the policy is _not_ used on a particular node then the work done\n to preload the policy (and to maintain it) is wasted.\"\n items:\n type: string\n type: array\n selector:\n description: \"The selector is an expression used to pick out the endpoints\n that the policy should be applied to. \\n Selector expressions follow\n this syntax: \\n \\tlabel == \\\"string_literal\\\" -> comparison, e.g.\n my_label == \\\"foo bar\\\" \\tlabel != \\\"string_literal\\\" -> not\n equal; also matches if label is not present \\tlabel in { \\\"a\\\",\n \\\"b\\\", \\\"c\\\", ... } -> true if the value of label X is one of\n \\\"a\\\", \\\"b\\\", \\\"c\\\" \\tlabel not in { \\\"a\\\", \\\"b\\\", \\\"c\\\", ... }\n \\ -> true if the value of label X is not one of \\\"a\\\", \\\"b\\\", \\\"c\\\"\n \\thas(label_name) -> True if that label is present \\t! expr ->\n negation of expr \\texpr && expr -> Short-circuit and \\texpr ||\n expr -> Short-circuit or \\t( expr ) -> parens for grouping \\tall()\n or the empty selector -> matches all endpoints. \\n Label names are\n allowed to contain alphanumerics, -, _ and /. String literals are\n more permissive but they do not support escape characters. \\n Examples\n (with made-up labels): \\n \\ttype == \\\"webserver\\\" && deployment\n == \\\"prod\\\" \\ttype in {\\\"frontend\\\", \\\"backend\\\"} \\tdeployment !=\n \\\"dev\\\" \\t! has(label_name)\"\n type: string\n serviceAccountSelector:\n description: ServiceAccountSelector is an optional field for an expression\n used to select a pod based on service accounts.\n type: string\n types:\n description: \"Types indicates whether this policy applies to ingress,\n or to egress, or to both. When not explicitly specified (and so\n the value on creation is empty or nil), Calico defaults Types according\n to what Ingress and Egress are present in the policy. The default\n is: \\n - [ PolicyTypeIngress ], if there are no Egress rules (including\n the case where there are also no Ingress rules) \\n - [ PolicyTypeEgress\n ], if there are Egress rules but no Ingress rules \\n - [ PolicyTypeIngress,\n PolicyTypeEgress ], if there are both Ingress and Egress rules.\n \\n When the policy is read back again, Types will always be one\n of these values, never empty or nil.\"\n items:\n description: PolicyType enumerates the possible values of the PolicySpec\n Types field.\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" + networkpolicies = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: networkpolicies.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: NetworkPolicy\n listKind: NetworkPolicyList\n plural: networkpolicies\n singular: networkpolicy\n preserveUnknownFields: false\n scope: Namespaced\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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 properties:\n egress:\n description: The ordered set of egress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n ingress:\n description: The ordered set of ingress rules. Each rule contains\n a set of packet match criteria and a corresponding action to apply.\n items:\n description: \"A Rule encapsulates a set of match criteria and an\n action. Both selector-based security Policy and security Profiles\n reference rules - separated out as a list of rules for both ingress\n and egress packet matching. \\n Each positive match criteria has\n a negated version, prefixed with \\\"Not\\\". All the match criteria\n within a rule must be satisfied for a packet to match. A single\n rule can contain the positive and negative version of a match\n and both must be satisfied for the rule to match.\"\n properties:\n action:\n type: string\n destination:\n description: Destination contains the match criteria that apply\n to destination entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n http:\n description: HTTP contains match criteria that apply to HTTP\n requests.\n properties:\n methods:\n description: Methods is an optional field that restricts\n the rule to apply only to HTTP requests that use one of\n the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple\n methods are OR'd together.\n items:\n type: string\n type: array\n paths:\n description: 'Paths is an optional field that restricts\n the rule to apply to HTTP requests that use one of the\n listed HTTP Paths. Multiple paths are OR''d together.\n e.g: - exact: /foo - prefix: /bar NOTE: Each entry may\n ONLY specify either a `exact` or a `prefix` match. The\n validator will check for it.'\n items:\n description: 'HTTPPath specifies an HTTP path to match.\n It may be either of the form: exact: : which matches\n the path exactly or prefix: : which matches\n the path prefix'\n properties:\n exact:\n type: string\n prefix:\n type: string\n type: object\n type: array\n type: object\n icmp:\n description: ICMP is an optional field that restricts the rule\n to apply to a specific type and code of ICMP traffic. This\n should only be specified if the Protocol field is set to \"ICMP\"\n or \"ICMPv6\".\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n ipVersion:\n description: IPVersion is an optional field that restricts the\n rule to only match a specific IP version.\n type: integer\n metadata:\n description: Metadata contains additional information for this\n rule\n properties:\n annotations:\n additionalProperties:\n type: string\n description: Annotations is a set of key value pairs that\n give extra information about the rule\n type: object\n type: object\n notICMP:\n description: NotICMP is the negated version of the ICMP field.\n properties:\n code:\n description: Match on a specific ICMP code. If specified,\n the Type value must also be specified. This is a technical\n limitation imposed by the kernel's iptables firewall,\n which Calico uses to enforce the rule.\n type: integer\n type:\n description: Match on a specific ICMP type. For example\n a value of 8 refers to ICMP Echo Request (i.e. pings).\n type: integer\n type: object\n notProtocol:\n anyOf:\n - type: integer\n - type: string\n description: NotProtocol is the negated version of the Protocol\n field.\n pattern: ^.*\n x-kubernetes-int-or-string: true\n protocol:\n anyOf:\n - type: integer\n - type: string\n description: \"Protocol is an optional field that restricts the\n rule to only apply to traffic of a specific IP protocol. Required\n if any of the EntityRules contain Ports (because ports only\n apply to certain protocols). \\n Must be one of these string\n values: \\\"TCP\\\", \\\"UDP\\\", \\\"ICMP\\\", \\\"ICMPv6\\\", \\\"SCTP\\\",\n \\\"UDPLite\\\" or an integer in the range 1-255.\"\n pattern: ^.*\n x-kubernetes-int-or-string: true\n source:\n description: Source contains the match criteria that apply to\n source entity.\n properties:\n namespaceSelector:\n description: \"NamespaceSelector is an optional field that\n contains a selector expression. Only traffic that originates\n from (or terminates at) endpoints within the selected\n namespaces will be matched. When both NamespaceSelector\n and another selector are defined on the same rule, then\n only workload endpoints that are matched by both selectors\n will be selected by the rule. \\n For NetworkPolicy, an\n empty NamespaceSelector implies that the Selector is limited\n to selecting only workload endpoints in the same namespace\n as the NetworkPolicy. \\n For NetworkPolicy, `global()`\n NamespaceSelector implies that the Selector is limited\n to selecting only GlobalNetworkSet or HostEndpoint. \\n\n For GlobalNetworkPolicy, an empty NamespaceSelector implies\n the Selector applies to workload endpoints across all\n namespaces.\"\n type: string\n nets:\n description: Nets is an optional field that restricts the\n rule to only apply to traffic that originates from (or\n terminates at) IP addresses in any of the given subnets.\n items:\n type: string\n type: array\n notNets:\n description: NotNets is the negated version of the Nets\n field.\n items:\n type: string\n type: array\n notPorts:\n description: NotPorts is the negated version of the Ports\n field. Since only some protocols have ports, if any ports\n are specified it requires the Protocol match in the Rule\n to be set to \"TCP\" or \"UDP\".\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n notSelector:\n description: NotSelector is the negated version of the Selector\n field. See Selector field for subtleties with negated\n selectors.\n type: string\n ports:\n description: \"Ports is an optional field that restricts\n the rule to only apply to traffic that has a source (destination)\n port that matches one of these ranges/values. This value\n is a list of integers or strings that represent ranges\n of ports. \\n Since only some protocols have ports, if\n any ports are specified it requires the Protocol match\n in the Rule to be set to \\\"TCP\\\" or \\\"UDP\\\".\"\n items:\n anyOf:\n - type: integer\n - type: string\n pattern: ^.*\n x-kubernetes-int-or-string: true\n type: array\n selector:\n description: \"Selector is an optional field that contains\n a selector expression (see Policy for sample syntax).\n \\ Only traffic that originates from (terminates at) endpoints\n matching the selector will be matched. \\n Note that: in\n addition to the negated version of the Selector (see NotSelector\n below), the selector expression syntax itself supports\n negation. The two types of negation are subtly different.\n One negates the set of matched endpoints, the other negates\n the whole match: \\n \\tSelector = \\\"!has(my_label)\\\" matches\n packets that are from other Calico-controlled \\tendpoints\n that do not have the label \\\"my_label\\\". \\n \\tNotSelector\n = \\\"has(my_label)\\\" matches packets that are not from\n Calico-controlled \\tendpoints that do have the label \\\"my_label\\\".\n \\n The effect is that the latter will accept packets from\n non-Calico sources whereas the former is limited to packets\n from Calico-controlled endpoints.\"\n type: string\n serviceAccounts:\n description: ServiceAccounts is an optional field that restricts\n the rule to only apply to traffic that originates from\n (or terminates at) a pod running as a matching service\n account.\n properties:\n names:\n description: Names is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account whose name is in the list.\n items:\n type: string\n type: array\n selector:\n description: Selector is an optional field that restricts\n the rule to only apply to traffic that originates\n from (or terminates at) a pod running as a service\n account that matches the given label selector. If\n both Names and Selector are specified then they are\n AND'ed.\n type: string\n type: object\n services:\n description: \"Services is an optional field that contains\n options for matching Kubernetes Services. If specified,\n only traffic that originates from or terminates at endpoints\n within the selected service(s) will be matched, and only\n to/from each endpoint's port. \\n Services cannot be specified\n on the same rule as Selector, NotSelector, NamespaceSelector,\n Nets, NotNets or ServiceAccounts. \\n Ports and NotPorts\n can only be specified with Services on ingress rules.\"\n properties:\n name:\n description: Name specifies the name of a Kubernetes\n Service to match.\n type: string\n namespace:\n description: Namespace specifies the namespace of the\n given Service. If left empty, the rule will match\n within this policy's namespace.\n type: string\n type: object\n type: object\n required:\n - action\n type: object\n type: array\n order:\n description: Order is an optional field that specifies the order in\n which the policy is applied. Policies with higher \"order\" are applied\n after those with lower order within the same tier. If the order\n is omitted, it may be considered to be \"infinite\" - i.e. the policy\n will be applied last. Policies with identical order will be applied\n in alphanumerical order based on the Policy \"Name\" within the tier.\n type: number\n performanceHints:\n description: \"PerformanceHints contains a list of hints to Calico's\n policy engine to help process the policy more efficiently. Hints\n never change the enforcement behaviour of the policy. \\n Currently,\n the only available hint is \\\"AssumeNeededOnEveryNode\\\". When that\n hint is set on a policy, Felix will act as if the policy matches\n a local endpoint even if it does not. This is useful for \\\"preloading\\\"\n any large static policies that are known to be used on every node.\n If the policy is _not_ used on a particular node then the work done\n to preload the policy (and to maintain it) is wasted.\"\n items:\n type: string\n type: array\n selector:\n description: \"The selector is an expression used to pick out the endpoints\n that the policy should be applied to. \\n Selector expressions follow\n this syntax: \\n \\tlabel == \\\"string_literal\\\" -> comparison, e.g.\n my_label == \\\"foo bar\\\" \\tlabel != \\\"string_literal\\\" -> not\n equal; also matches if label is not present \\tlabel in { \\\"a\\\",\n \\\"b\\\", \\\"c\\\", ... } -> true if the value of label X is one of\n \\\"a\\\", \\\"b\\\", \\\"c\\\" \\tlabel not in { \\\"a\\\", \\\"b\\\", \\\"c\\\", ... }\n \\ -> true if the value of label X is not one of \\\"a\\\", \\\"b\\\", \\\"c\\\"\n \\thas(label_name) -> True if that label is present \\t! expr ->\n negation of expr \\texpr && expr -> Short-circuit and \\texpr ||\n expr -> Short-circuit or \\t( expr ) -> parens for grouping \\tall()\n or the empty selector -> matches all endpoints. \\n Label names are\n allowed to contain alphanumerics, -, _ and /. String literals are\n more permissive but they do not support escape characters. \\n Examples\n (with made-up labels): \\n \\ttype == \\\"webserver\\\" && deployment\n == \\\"prod\\\" \\ttype in {\\\"frontend\\\", \\\"backend\\\"} \\tdeployment !=\n \\\"dev\\\" \\t! has(label_name)\"\n type: string\n serviceAccountSelector:\n description: ServiceAccountSelector is an optional field for an expression\n used to select a pod based on service accounts.\n type: string\n tier:\n description: The name of the tier that this policy belongs to. If\n this is omitted, the default tier (name is \"default\") is assumed. The\n specified tier must exist in order to create security policies within\n the tier, the \"default\" tier is created automatically if it does\n not exist, this means for deployments requiring only a single Tier,\n the tier name may be omitted on all policy management requests.\n type: string\n types:\n description: \"Types indicates whether this policy applies to ingress,\n or to egress, or to both. When not explicitly specified (and so\n the value on creation is empty or nil), Calico defaults Types according\n to what Ingress and Egress are present in the policy. The default\n is: \\n - [ PolicyTypeIngress ], if there are no Egress rules (including\n the case where there are also no Ingress rules) \\n - [ PolicyTypeEgress\n ], if there are Egress rules but no Ingress rules \\n - [ PolicyTypeIngress,\n PolicyTypeEgress ], if there are both Ingress and Egress rules.\n \\n When the policy is read back again, Types will always be one\n of these values, never empty or nil.\"\n items:\n description: PolicyType enumerates the possible values of the PolicySpec\n Types field.\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" networksets = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: networksets.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: NetworkSet\n listKind: NetworkSetList\n plural: networksets\n singular: networkset\n preserveUnknownFields: false\n scope: Namespaced\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n description: NetworkSet is the Namespaced-equivalent of the GlobalNetworkSet.\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: NetworkSetSpec contains the specification for a NetworkSet\n resource.\n properties:\n nets:\n description: The list of IP networks that belong to this set.\n items:\n type: string\n type: array\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" + tiers = "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n annotations:\n controller-gen.kubebuilder.io/version: (devel)\n creationTimestamp: null\n name: tiers.crd.projectcalico.org\nspec:\n group: crd.projectcalico.org\n names:\n kind: Tier\n listKind: TierList\n plural: tiers\n singular: tier\n scope: Cluster\n versions:\n - name: v1\n schema:\n openAPIV3Schema:\n properties:\n apiVersion:\n description: 'APIVersion defines the versioned schema of this representation\n of an object. Servers should convert recognized schemas to the latest\n internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n type: string\n kind:\n description: 'Kind is a string value representing the REST resource this\n object represents. Servers may infer this from the endpoint the client\n submits requests to. Cannot be updated. In CamelCase. 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: TierSpec contains the specification for a security policy\n tier resource.\n properties:\n defaultAction:\n description: 'DefaultAction specifies the action applied to workloads\n selected by a policy in the tier, but not rule matched the workload''s\n traffic. [Default: Deny]'\n enum:\n - Pass\n - Deny\n type: string\n order:\n description: Order is an optional field that specifies the order in\n which the tier is applied. Tiers with higher \"order\" are applied\n after those with lower order. If the order is omitted, it may be\n considered to be \"infinite\" - i.e. the tier will be applied last. Tiers\n with identical order will be applied in alphanumerical order based\n on the Tier \"Name\".\n type: number\n type: object\n type: object\n served: true\n storage: true\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: []\n storedVersions: []\n" ) diff --git a/calicoctl/calicoctl/commands/create.go b/calicoctl/calicoctl/commands/create.go index e244e9a3fe6..2ca9da20488 100644 --- a/calicoctl/calicoctl/commands/create.go +++ b/calicoctl/calicoctl/commands/create.go @@ -65,21 +65,7 @@ Description: Valid resource types are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * networkSet - * node - * profile - * workloadEndpoint - + Attempting to create a resource that already exists is treated as a terminating error unless the --skip-exists flag is set. If this flag is set, resources that already exist are skipped. @@ -96,6 +82,9 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) diff --git a/calicoctl/calicoctl/commands/datastore/migrate/export.go b/calicoctl/calicoctl/commands/datastore/migrate/export.go index 2aecf6594c2..b4a5adecc61 100644 --- a/calicoctl/calicoctl/commands/datastore/migrate/export.go +++ b/calicoctl/calicoctl/commands/datastore/migrate/export.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import ( "strings" "github.com/docopt/docopt-go" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" "golang.org/x/text/cases" "golang.org/x/text/language" "k8s.io/apimachinery/pkg/api/meta" @@ -36,7 +36,7 @@ import ( "github.com/projectcalico/calico/calicoctl/calicoctl/util" "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" - "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" + "github.com/projectcalico/calico/libcalico-go/lib/names" ) var title = cases.Title(language.English) @@ -57,6 +57,8 @@ var allV3Resources []string = []string{ "nodes", "bgpconfigs", "felixconfigs", + "ipreservations", + "bgpfilters", } var resourceDisplayMap map[string]string = map[string]string{ @@ -65,7 +67,7 @@ var resourceDisplayMap map[string]string = map[string]string{ "ipamhandles": "IPAMHandles", "ipamconfigs": "IPAMConfigurations", "ippools": "IPPools", - "bgpconfig": "BGPConfigurations", + "bgpconfigs": "BGPConfigurations", "bgppeers": "BGPPeers", "clusterinfos": "ClusterInformations", "felixconfigs": "FelixConfigurations", @@ -76,11 +78,13 @@ var resourceDisplayMap map[string]string = map[string]string{ "networkpolicies": "NetworkPolicies", "networksets": "Networksets", "nodes": "Nodes", + "ipreservations": "IPReservations", + "bgpfilters": "BGPFilters", } var namespacedResources map[string]struct{} = map[string]struct{}{ - "networkpolicies": struct{}{}, - "networksets": struct{}{}, + "networkpolicies": {}, + "networksets": {}, } func Export(args []string) error { @@ -99,25 +103,12 @@ Description: in yaml and json format. Save the results of this command to a file for later use with the import command. - The resources exported include the following: - - IPAMBlocks - - BlockAffinities - - IPAMHandles - - IPAMConfigurations - - IPPools - - BGPConfigurations - - BGPPeers - - ClusterInformations - - FelixConfigurations - - GlobalNetworkPolicies - - GlobalNetworkSets - - HostEndpoints - - KubeControllersConfigurations - - NetworkPolicies - - Networksets - - Nodes + The following resources are exported: + + The following resources are not exported: + - WorkloadEndpoints - Profiles ` @@ -125,6 +116,13 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resources that will be exported. + resourceList := "" + for _, r := range allV3Resources { + resourceList += fmt.Sprintf(" - %s\n", resourceDisplayMap[r]) + } + doc = strings.Replace(doc, "", resourceList, 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) @@ -157,7 +155,7 @@ Description: // Check that the datastore configured datastore is etcd cfg, err := clientmgr.LoadClientConfig(cf) if err != nil { - log.Info("Error loading config") + logrus.Info("Error loading config") return err } @@ -192,7 +190,7 @@ Description: errStr += "\n" } } - return fmt.Errorf(errStr) + return fmt.Errorf("%s", errStr) } for i, resource := range results.Resources { @@ -223,7 +221,7 @@ Description: if !ok { return fmt.Errorf("Unable to convert Calico network policy for inspection") } - if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), conversion.K8sNetworkPolicyNamePrefix) { + if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sNetworkPolicyNamePrefix) { filtered = append(filtered, obj) } } @@ -235,6 +233,31 @@ Description: results.Resources[i] = resource } + // Skip exporting Kubernetes admin network policies. + if r == "globalnetworkpolicies" { + objs, err := meta.ExtractList(resource) + if err != nil { + return fmt.Errorf("Error extracting global network policies for inspection before exporting: %s", err) + } + + filtered := []runtime.Object{} + for _, obj := range objs { + metaObj, ok := obj.(v1.ObjectMetaAccessor) + if !ok { + return fmt.Errorf("Unable to convert Calico gloabal network policy for inspection") + } + if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sAdminNetworkPolicyNamePrefix) { + filtered = append(filtered, obj) + } + } + + err = meta.SetList(resource, filtered) + if err != nil { + return fmt.Errorf("Unable to remove Kubernetes admin network policies for export: %s", err) + } + results.Resources[i] = resource + } + // Nodes need to also be modified to move the Orchestrator reference to the name field. if r == "nodes" { err := meta.EachListItem(resource, func(obj runtime.Object) error { @@ -356,7 +379,7 @@ Description: errStr += "\n" } } - return fmt.Errorf(errStr) + return fmt.Errorf("%s", errStr) } // Denote separation between resources stored in YAML and the JSON IPAM resources. diff --git a/calicoctl/calicoctl/commands/datastore/migrate/import.go b/calicoctl/calicoctl/commands/datastore/migrate/import.go index a26a8de32a9..976a078fc32 100644 --- a/calicoctl/calicoctl/commands/datastore/migrate/import.go +++ b/calicoctl/calicoctl/commands/datastore/migrate/import.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,10 +40,10 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s" - "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" calicoErrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" ) @@ -246,7 +246,25 @@ func checkCalicoResourcesNotExist(args map[string]interface{}, c client.Interfac } // Make sure that the network policy is a K8s network policy - if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), conversion.K8sNetworkPolicyNamePrefix) { + if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sNetworkPolicyNamePrefix) { + return fmt.Errorf("Found existing Calico %s resource", results.SingleKind) + } + } + } else if r == "globalnetworkpolicies" { + // For globalnetworkpolicies, having K8s admin network policies should not throw an error + objs, err := meta.ExtractList(resource) + if err != nil { + return fmt.Errorf("Error extracting global network policies for inspection: %s", err) + } + + for _, obj := range objs { + metaObj, ok := obj.(v1.ObjectMetaAccessor) + if !ok { + return fmt.Errorf("Unable to convert Calico global network policy for inspection") + } + + // Make sure that the global network policy is a K8s admin network policy + if !strings.HasPrefix(metaObj.GetObjectMeta().GetName(), names.K8sAdminNetworkPolicyNamePrefix) { return fmt.Errorf("Found existing Calico %s resource", results.SingleKind) } } diff --git a/calicoctl/calicoctl/commands/datastore/migrate/migrateipam_test.go b/calicoctl/calicoctl/commands/datastore/migrate/migrateipam_test.go index a46a59f5da7..545577b1eae 100644 --- a/calicoctl/calicoctl/commands/datastore/migrate/migrateipam_test.go +++ b/calicoctl/calicoctl/commands/datastore/migrate/migrateipam_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -183,6 +183,10 @@ func NewMockIPAMClient(bc bapi.Client) client.Interface { } } +func (c *MockIPAMClient) Tiers() client.TierInterface { + return nil +} + func (c *MockIPAMClient) Backend() bapi.Client { return c.backend } diff --git a/calicoctl/calicoctl/commands/delete.go b/calicoctl/calicoctl/commands/delete.go index 0aa46a427b6..e911f7d42d3 100644 --- a/calicoctl/calicoctl/commands/delete.go +++ b/calicoctl/calicoctl/commands/delete.go @@ -71,21 +71,7 @@ Description: Valid resource types are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * networkSet - * node - * profile - * workloadEndpoint - + The resource type is case-insensitive and may be pluralized. Attempting to delete a resource that does not exists is treated as a @@ -108,6 +94,9 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) @@ -149,7 +138,7 @@ Description: errStr += fmt.Sprintf("Failed to delete resource: %v\n", err) } } - return fmt.Errorf(errStr) + return fmt.Errorf("%s", errStr) } return nil diff --git a/calicoctl/calicoctl/commands/get.go b/calicoctl/calicoctl/commands/get.go index fed0149e852..2b3100bde45 100644 --- a/calicoctl/calicoctl/commands/get.go +++ b/calicoctl/calicoctl/commands/get.go @@ -15,12 +15,12 @@ package commands import ( - "github.com/docopt/docopt-go" - "fmt" "os" "strings" + "github.com/docopt/docopt-go" + log "github.com/sirupsen/logrus" "github.com/projectcalico/calico/calicoctl/calicoctl/commands/argutils" @@ -74,21 +74,7 @@ Description: Valid resource types are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * networkSet - * node - * profile - * workloadEndpoint - + The resource type is case-insensitive and may be pluralized. Attempting to get resources that do not exist will simply return no results. @@ -127,6 +113,9 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + // -a option Backward compatibility for k, v := range args { if v == "-a" { @@ -220,7 +209,7 @@ Description: errStr += "\n" } } - return fmt.Errorf(errStr) + return fmt.Errorf("%s", errStr) } return nil diff --git a/calicoctl/calicoctl/commands/label.go b/calicoctl/calicoctl/commands/label.go index b4fd5c0ff90..1673ca5fdad 100644 --- a/calicoctl/calicoctl/commands/label.go +++ b/calicoctl/calicoctl/commands/label.go @@ -71,20 +71,7 @@ Description: The label command is used to add or update a label on a resource. Resource types that can be labeled are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * node - * profile - * workloadEndpoint - + The resource type is case-insensitive and may be pluralized. Attempting to label resources that do not exist will get an error. @@ -99,6 +86,9 @@ Description: binaryName, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", binaryName) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) diff --git a/calicoctl/calicoctl/commands/node/run.go b/calicoctl/calicoctl/commands/node/run.go index b6f021512ac..ac2bf85649c 100644 --- a/calicoctl/calicoctl/commands/node/run.go +++ b/calicoctl/calicoctl/commands/node/run.go @@ -374,7 +374,7 @@ Description: for _, line := range strings.Split(string(output), "/n") { errStr += fmt.Sprintf(" | %s/n", line) } - return fmt.Errorf(errStr) + return fmt.Errorf("%s", errStr) } // Create the command to follow the docker logs for the calico/node diff --git a/calicoctl/calicoctl/commands/patch.go b/calicoctl/calicoctl/commands/patch.go index 838fcfe3dc7..354adad6cfd 100644 --- a/calicoctl/calicoctl/commands/patch.go +++ b/calicoctl/calicoctl/commands/patch.go @@ -60,21 +60,7 @@ Description: Valid resource types are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * networkSet - * node - * profile - * workloadEndpoint - + The resource type is case-insensitive and may be pluralized. Attempting to patch a resource that does not exists is treated as a @@ -90,6 +76,9 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) @@ -121,7 +110,7 @@ Description: for _, err := range results.ResErrs { errStr += fmt.Sprintf("Failed to patch '%s' resource: %v\n", results.SingleKind, err) } - return fmt.Errorf(errStr) + return fmt.Errorf("%s", errStr) } return nil diff --git a/calicoctl/calicoctl/commands/replace.go b/calicoctl/calicoctl/commands/replace.go index cd90d836d19..47119767043 100644 --- a/calicoctl/calicoctl/commands/replace.go +++ b/calicoctl/calicoctl/commands/replace.go @@ -64,21 +64,7 @@ Description: Valid resource types are: - * bgpConfiguration - * bgpPeer - * felixConfiguration - * globalNetworkPolicy - * globalNetworkSet - * hostEndpoint - * ipPool - * ipReservation - * kubeControllersConfiguration - * networkPolicy - * networkSet - * node - * profile - * workloadEndpoint - + Attempting to replace a resource that does not exist is treated as a terminating error. @@ -96,6 +82,9 @@ Description: name, _ := util.NameAndDescription() doc = strings.ReplaceAll(doc, "", name) + // Replace with the list of resource types. + doc = strings.Replace(doc, "", util.Resources(), 1) + parsedArgs, err := docopt.ParseArgs(doc, args, "") if err != nil { return fmt.Errorf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.", strings.Join(args, " ")) diff --git a/calicoctl/calicoctl/resourcemgr/globalnetworkpolicy.go b/calicoctl/calicoctl/resourcemgr/globalnetworkpolicy.go index 2d7c7c27bf9..72b47d0eb7f 100644 --- a/calicoctl/calicoctl/resourcemgr/globalnetworkpolicy.go +++ b/calicoctl/calicoctl/resourcemgr/globalnetworkpolicy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,12 +16,15 @@ package resourcemgr import ( "context" + "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" ) @@ -31,23 +34,45 @@ func init() { newGlobalNetworkPolicyList(), false, []string{"globalnetworkpolicy", "globalnetworkpolicies", "gnp", "gnps"}, - []string{"NAME"}, - []string{"NAME", "ORDER", "SELECTOR"}, + []string{"NAME", "TIER"}, + []string{"NAME", "TIER", "ORDER", "SELECTOR"}, map[string]string{ "NAME": "{{.ObjectMeta.Name}}", "ORDER": "{{.Spec.Order}}", "SELECTOR": "{{.Spec.Selector}}", + "TIER": "{{.Spec.Tier}}", }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { r := resource.(*api.GlobalNetworkPolicy) + if strings.HasPrefix(r.Name, names.K8sAdminNetworkPolicyNamePrefix) { + return nil, cerrors.ErrorOperationNotSupported{ + Operation: "create or apply", + Identifier: resource, + Reason: "kubernetes admin network policies must be managed through the kubernetes API", + } + } return client.GlobalNetworkPolicies().Create(ctx, r, options.SetOptions{}) }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { r := resource.(*api.GlobalNetworkPolicy) + if strings.HasPrefix(r.Name, names.K8sAdminNetworkPolicyNamePrefix) { + return nil, cerrors.ErrorOperationNotSupported{ + Operation: "create or apply", + Identifier: resource, + Reason: "kubernetes admin network policies must be managed through the kubernetes API", + } + } return client.GlobalNetworkPolicies().Update(ctx, r, options.SetOptions{}) }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { r := resource.(*api.GlobalNetworkPolicy) + if strings.HasPrefix(r.Name, names.K8sAdminNetworkPolicyNamePrefix) { + return nil, cerrors.ErrorOperationNotSupported{ + Operation: "create or apply", + Identifier: resource, + Reason: "kubernetes admin network policies must be managed through the kubernetes API", + } + } return client.GlobalNetworkPolicies().Delete(ctx, r.Name, options.DeleteOptions{ResourceVersion: r.ResourceVersion}) }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { diff --git a/calicoctl/calicoctl/resourcemgr/networkpolicy.go b/calicoctl/calicoctl/resourcemgr/networkpolicy.go index 7383f03691c..e23277cd4ea 100644 --- a/calicoctl/calicoctl/resourcemgr/networkpolicy.go +++ b/calicoctl/calicoctl/resourcemgr/networkpolicy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,13 +18,12 @@ import ( "context" "strings" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" ) @@ -34,18 +33,19 @@ func init() { newNetworkPolicyList(), true, []string{"networkpolicy", "networkpolicies", "policy", "np", "policies", "pol", "pols"}, - []string{"NAME"}, - []string{"NAME", "ORDER", "SELECTOR"}, + []string{"NAME", "TIER"}, + []string{"NAME", "TIER", "ORDER", "SELECTOR"}, // NAMESPACE may be prepended in GrabTableTemplate so needs to remain in the map below map[string]string{ "NAME": "{{.ObjectMeta.Name}}", "NAMESPACE": "{{.ObjectMeta.Namespace}}", "ORDER": "{{.Spec.Order}}", "SELECTOR": "{{.Spec.Selector}}", + "TIER": "{{.Spec.Tier}}", }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { r := resource.(*api.NetworkPolicy) - if strings.HasPrefix(r.Name, conversion.K8sNetworkPolicyNamePrefix) { + if strings.HasPrefix(r.Name, names.K8sNetworkPolicyNamePrefix) { return nil, cerrors.ErrorOperationNotSupported{ Operation: "create or apply", Identifier: resource, @@ -56,7 +56,7 @@ func init() { }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { r := resource.(*api.NetworkPolicy) - if strings.HasPrefix(r.Name, conversion.K8sNetworkPolicyNamePrefix) { + if strings.HasPrefix(r.Name, names.K8sNetworkPolicyNamePrefix) { return nil, cerrors.ErrorOperationNotSupported{ Operation: "apply or replace", Identifier: resource, @@ -67,7 +67,7 @@ func init() { }, func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { r := resource.(*api.NetworkPolicy) - if strings.HasPrefix(r.Name, conversion.K8sNetworkPolicyNamePrefix) { + if strings.HasPrefix(r.Name, names.K8sNetworkPolicyNamePrefix) { return nil, cerrors.ErrorOperationNotSupported{ Operation: "delete", Identifier: resource, diff --git a/calicoctl/calicoctl/resourcemgr/resourcemgr.go b/calicoctl/calicoctl/resourcemgr/resourcemgr.go index 53c9d167fd4..09a40effa07 100644 --- a/calicoctl/calicoctl/resourcemgr/resourcemgr.go +++ b/calicoctl/calicoctl/resourcemgr/resourcemgr.go @@ -69,8 +69,10 @@ type ResourceListObject interface { v1.ListMetaAccessor } -type ResourceActionCommand func(context.Context, client.Interface, ResourceObject) (ResourceObject, error) -type ResourceListActionCommand func(context.Context, client.Interface, ResourceObject) (ResourceListObject, error) +type ( + ResourceActionCommand func(context.Context, client.Interface, ResourceObject) (ResourceObject, error) + ResourceListActionCommand func(context.Context, client.Interface, ResourceObject) (ResourceListObject, error) +) // ResourceHelper encapsulates details about a specific version of a specific resource: // @@ -100,19 +102,26 @@ type resourceHelper struct { func (rh resourceHelper) String() string { if !rh.isList { return fmt.Sprintf("Resource(%s %s)", rh.resource.GetObjectKind(), rh.resource.GetObjectKind().GroupVersionKind()) - } return fmt.Sprintf("Resource(%s %s)", rh.listResource.GetObjectKind(), rh.listResource.GetListMeta().GetResourceVersion()) } // Store a resourceHelper for each resource. -var helpers map[schema.GroupVersionKind]resourceHelper -var kindToRes = make(map[string]ResourceObject) +var ( + helpers map[schema.GroupVersionKind]resourceHelper + kindToRes = make(map[string]ResourceObject) + allKinds = []string{} +) + +// ValidResources returns all registered resource kinds. +func ValidResources() []string { + return allKinds +} func registerResource(res ResourceObject, resList ResourceListObject, isNamespaced bool, names []string, tableHeadings []string, tableHeadingsWide []string, headingsMap map[string]string, - create, update, delete, get ResourceActionCommand, list ResourceListActionCommand) { - + create, update, delete, get ResourceActionCommand, list ResourceListActionCommand, +) { if helpers == nil { helpers = make(map[schema.GroupVersionKind]resourceHelper) } @@ -146,6 +155,7 @@ func registerResource(res ResourceObject, resList ResourceListObject, isNamespac for _, v := range names { kindToRes[v] = res } + allKinds = append(allKinds, res.GetObjectKind().GroupVersionKind().Kind) } func (rh resourceHelper) GetObjectType() reflect.Type { @@ -228,7 +238,7 @@ func (rh resourceHelper) Update(ctx context.Context, client client.Interface, re id = fmt.Sprintf("%s(%s/%s)", ro.GetObjectKind().GroupVersionKind().GroupKind().Kind, ro.GetObjectMeta().GetNamespace(), ro.GetObjectMeta().GetName()) } return ro, cerrors.ErrorResourceUpdateConflict{ - Err: fmt.Errorf(fmt.Sprintf("Resource version '%s' is out of date (latest: %s). Update the resource YAML/JSON in order to make changes.", rv, ro.GetObjectMeta().GetResourceVersion())), + Err: fmt.Errorf("Resource version '%s' is out of date (latest: %s). Update the resource YAML/JSON in order to make changes.", rv, ro.GetObjectMeta().GetResourceVersion()), Identifier: id, } } diff --git a/calicoctl/calicoctl/resourcemgr/tier.go b/calicoctl/calicoctl/resourcemgr/tier.go new file mode 100644 index 00000000000..ee0ebaa1373 --- /dev/null +++ b/calicoctl/calicoctl/resourcemgr/tier.go @@ -0,0 +1,66 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package resourcemgr + +import ( + "context" + "sort" + + api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/options" +) + +func init() { + registerResource( + api.NewTier(), + api.NewTierList(), + false, + []string{"tier", "tiers"}, + []string{"NAME", "ORDER"}, + []string{"NAME", "ORDER"}, + map[string]string{ + "NAME": "{{.ObjectMeta.Name}}", + "ORDER": "{{.Spec.Order}}", + }, + func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { + r := resource.(*api.Tier) + return client.Tiers().Create(ctx, r, options.SetOptions{}) + }, + func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { + r := resource.(*api.Tier) + return client.Tiers().Update(ctx, r, options.SetOptions{}) + }, + func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { + r := resource.(*api.Tier) + return client.Tiers().Delete(ctx, r.Name, options.DeleteOptions{ResourceVersion: r.ResourceVersion}) + }, + func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceObject, error) { + r := resource.(*api.Tier) + return client.Tiers().Get(ctx, r.Name, options.GetOptions{ResourceVersion: r.ResourceVersion}) + }, + func(ctx context.Context, client client.Interface, resource ResourceObject) (ResourceListObject, error) { + r := resource.(*api.Tier) + tierList, err := client.Tiers().List(ctx, options.ListOptions{ResourceVersion: r.ResourceVersion, Name: r.Name}) + if err != nil { + return tierList, err + } + + // Sort the output by order + sort.SliceStable(tierList.Items, func(tier1, tier2 int) bool { + if tierList.Items[tier1].Spec.Order == nil { + return false + } + + if tierList.Items[tier2].Spec.Order == nil { + return true + } + + return *tierList.Items[tier1].Spec.Order < *tierList.Items[tier2].Spec.Order + }) + + return tierList, nil + }, + ) +} diff --git a/calicoctl/calicoctl/util/docstring.go b/calicoctl/calicoctl/util/docstring.go index a5f1563d60a..7e6090f3395 100644 --- a/calicoctl/calicoctl/util/docstring.go +++ b/calicoctl/calicoctl/util/docstring.go @@ -1,9 +1,13 @@ package util import ( + "fmt" "os" "path/filepath" + "sort" "strings" + + "github.com/projectcalico/calico/calicoctl/calicoctl/resourcemgr" ) func NameAndDescription() (string, string) { @@ -18,3 +22,15 @@ func NameAndDescription() (string, string) { } return name, desc } + +// Resources returns a string to insert into the docstring that lists the valid registered resources in use by +// calicoctl, sorted alphabetically. +func Resources() string { + kinds := resourcemgr.ValidResources() + sort.Strings(kinds) + resourceList := "" + for _, r := range kinds { + resourceList += fmt.Sprintf(" - %s\n", strings.ToLower(r)) + } + return resourceList +} diff --git a/calicoctl/test-data/convert/output/v1/migration/policy.json b/calicoctl/test-data/convert/output/v1/migration/policy.json index 9f23faf9615..e3af08b62fa 100644 --- a/calicoctl/test-data/convert/output/v1/migration/policy.json +++ b/calicoctl/test-data/convert/output/v1/migration/policy.json @@ -7,13 +7,17 @@ "kind": "GlobalNetworkPolicy", "apiVersion": "projectcalico.org/v3", "metadata": { - "name": "allow-tcp-6379", + "name": "default.allow-tcp-6379", "creationTimestamp": null, + "labels": { + "projectcalico.org/tier": "default" + }, "annotations": { "aname": "avalue" } }, "spec": { + "tier": "default", "order": 1234, "ingress": [ { @@ -113,10 +117,14 @@ "kind": "GlobalNetworkPolicy", "apiVersion": "projectcalico.org/v3", "metadata": { - "name": "allow-tcp-555-donottrack", - "creationTimestamp": null + "name": "default.allow-tcp-555-donottrack", + "creationTimestamp": null, + "labels": { + "projectcalico.org/tier": "default" + } }, "spec": { + "tier": "default", "order": 1230, "ingress": [ { diff --git a/calicoctl/test-data/convert/output/v1/migration/policy.yaml b/calicoctl/test-data/convert/output/v1/migration/policy.yaml index 66bb1a81caf..0f7597e662a 100644 --- a/calicoctl/test-data/convert/output/v1/migration/policy.yaml +++ b/calicoctl/test-data/convert/output/v1/migration/policy.yaml @@ -6,7 +6,9 @@ items: annotations: aname: avalue creationTimestamp: null - name: allow-tcp-6379 + labels: + projectcalico.org/tier: default + name: default.allow-tcp-6379 spec: egress: - action: Allow @@ -63,6 +65,7 @@ items: - 172.18.0.0/16 order: 1234 selector: role == 'database' && !has(demo) + tier: default types: - Ingress - Egress @@ -70,7 +73,9 @@ items: kind: GlobalNetworkPolicy metadata: creationTimestamp: null - name: allow-tcp-555-donottrack + labels: + projectcalico.org/tier: default + name: default.allow-tcp-555-donottrack spec: applyOnForward: true doNotTrack: true @@ -84,6 +89,7 @@ items: selector: role == 'cache' order: 1230 selector: role == 'database' + tier: default types: - Ingress kind: List diff --git a/calicoctl/test-data/convert/output/v1/test3.json b/calicoctl/test-data/convert/output/v1/test3.json index 20fad7dcad0..3e0e0208ac1 100644 --- a/calicoctl/test-data/convert/output/v1/test3.json +++ b/calicoctl/test-data/convert/output/v1/test3.json @@ -2,10 +2,14 @@ "kind": "GlobalNetworkPolicy", "apiVersion": "projectcalico.org/v3", "metadata": { - "name": "policy1", - "creationTimestamp": null + "name": "default.policy1", + "creationTimestamp": null, + "labels": { + "projectcalico.org/tier": "default" + } }, "spec": { + "tier": "default", "order": 100, "ingress": [ { diff --git a/calicoctl/test-data/convert/output/v1/test3.yaml b/calicoctl/test-data/convert/output/v1/test3.yaml index 16c5d47af5b..9a9a2b2355e 100644 --- a/calicoctl/test-data/convert/output/v1/test3.yaml +++ b/calicoctl/test-data/convert/output/v1/test3.yaml @@ -2,7 +2,9 @@ apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: creationTimestamp: null - name: policy1 + labels: + projectcalico.org/tier: default + name: default.policy1 spec: ingress: - action: Deny @@ -11,5 +13,6 @@ spec: selector: type=='application' order: 100 selector: type=='database' + tier: default types: - Ingress diff --git a/calicoctl/tests/fv/ipam_test.go b/calicoctl/tests/fv/ipam_test.go index 5ecad6a54aa..fccd8425c89 100644 --- a/calicoctl/tests/fv/ipam_test.go +++ b/calicoctl/tests/fv/ipam_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,18 +25,17 @@ import ( "testing" . "github.com/onsi/gomega" - v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" - log "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - bapi "github.com/projectcalico/calico/libcalico-go/lib/backend/api" - "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s" - "github.com/projectcalico/calico/libcalico-go/lib/backend/model" + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" ipamcmd "github.com/projectcalico/calico/calicoctl/calicoctl/commands/ipam" . "github.com/projectcalico/calico/calicoctl/tests/fv/utils" libapi "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" + bapi "github.com/projectcalico/calico/libcalico-go/lib/backend/api" + "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s" + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" "github.com/projectcalico/calico/libcalico-go/lib/clientv3" "github.com/projectcalico/calico/libcalico-go/lib/ipam" "github.com/projectcalico/calico/libcalico-go/lib/logutils" @@ -45,8 +44,8 @@ import ( ) func init() { - log.AddHook(logutils.ContextHook{}) - log.SetFormatter(&logutils.Formatter{}) + // Set up logging formatting. + logutils.ConfigureFormatter("test") } func TestIPAM(t *testing.T) { diff --git a/calicoctl/tests/fv/migrate_ipam_test.go b/calicoctl/tests/fv/migrate_ipam_test.go index 780b83d53a6..e7cb2792932 100644 --- a/calicoctl/tests/fv/migrate_ipam_test.go +++ b/calicoctl/tests/fv/migrate_ipam_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,8 +24,6 @@ import ( . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" - v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" . "github.com/projectcalico/calico/calicoctl/tests/fv/utils" @@ -39,8 +37,8 @@ import ( ) func init() { - log.AddHook(logutils.ContextHook{}) - log.SetFormatter(&logutils.Formatter{}) + // Set up logging formatting. + logutils.ConfigureFormatter("test") } func TestDatastoreMigrationIPAM(t *testing.T) { diff --git a/calicoctl/tests/fv/multi_context_test.go b/calicoctl/tests/fv/multi_context_test.go index 60353ad1434..28d1c71ec7d 100644 --- a/calicoctl/tests/fv/multi_context_test.go +++ b/calicoctl/tests/fv/multi_context_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ import ( "strings" "testing" - log "github.com/sirupsen/logrus" - . "github.com/onsi/gomega" . "github.com/projectcalico/calico/calicoctl/tests/fv/utils" @@ -27,8 +25,8 @@ import ( ) func init() { - log.AddHook(logutils.ContextHook{}) - log.SetFormatter(&logutils.Formatter{}) + // Set up logging formatting. + logutils.ConfigureFormatter("test") } func TestMultiCluster(t *testing.T) { diff --git a/calicoctl/tests/fv/namespace_option_test.go b/calicoctl/tests/fv/namespace_option_test.go index 86c35577f80..169517b9c9a 100644 --- a/calicoctl/tests/fv/namespace_option_test.go +++ b/calicoctl/tests/fv/namespace_option_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import ( "testing" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" @@ -31,8 +30,8 @@ import ( ) func init() { - log.AddHook(logutils.ContextHook{}) - log.SetFormatter(&logutils.Formatter{}) + // Set up logging formatting. + logutils.ConfigureFormatter("test") } func TestMultiOption(t *testing.T) { @@ -91,8 +90,6 @@ func TestMultiOption(t *testing.T) { Expect(out).To(Equal("IPPool is not namespaced\n")) out = Calicoctl(false, "get", "networkPolicy", "-A") - Expect(out).To(Equal("NAMESPACE NAME \nfirstns policy1 \nsecondns policy2 \n\n")) - - out = Calicoctl(false, "get", "networkPolicy", "-a") - Expect(out).To(Equal("NAMESPACE NAME \nfirstns policy1 \nsecondns policy2 \n\n")) + out2 := Calicoctl(false, "get", "networkPolicy", "-a") + Expect(out).To(Equal(out2)) } diff --git a/calicoctl/tests/st/calicoctl/test_convert.py b/calicoctl/tests/st/calicoctl/test_convert.py index 0f1bc35ec2a..49c97939c76 100644 --- a/calicoctl/tests/st/calicoctl/test_convert.py +++ b/calicoctl/tests/st/calicoctl/test_convert.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2017 Tigera, Inc. All rights reserved. +# Copyright (c) 2015-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -54,6 +54,9 @@ class TestCalicoctlConvert(TestBase): Test calicoctl convert """ + def setUp(self): + super(TestCalicoctlConvert, self).setUp() + def _test_convert(self, filename, applySuccess, format="yaml"): """ Test convert successfully diff --git a/calicoctl/tests/st/calicoctl/test_crud.py b/calicoctl/tests/st/calicoctl/test_crud.py index 26083b35230..d8bcf039a87 100644 --- a/calicoctl/tests/st/calicoctl/test_crud.py +++ b/calicoctl/tests/st/calicoctl/test_crud.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2021 Tigera, Inc. All rights reserved. +# Copyright (c) 2015-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ from tests.st.test_base import TestBase from tests.st.utils.utils import log_and_run, calicoctl, \ API_VERSION, name, ERROR_CONFLICT, NOT_FOUND, NOT_NAMESPACED, \ - SET_DEFAULT, NOT_SUPPORTED, KUBERNETES_NP, writeyaml + SET_DEFAULT, NOT_SUPPORTED, KUBERNETES_NP, writeyaml, add_tier_label, kind, namespace from tests.st.utils.data import * logging.basicConfig(level=logging.DEBUG, format="%(message)s") @@ -35,6 +35,9 @@ class TestCalicoctlCommands(TestBase): write tests for them (yet) """ + def setUp(self): + super(TestCalicoctlCommands, self).setUp() + def test_get(self): """ Test that a basic CRUD flow for pool commands works. @@ -115,14 +118,14 @@ def test_get_delete_multiple_names(self): rc.assert_no_error() # Get the 2 resources by name - rc = calicoctl("get ippool %s %s" % (name(ippool_name1_rev1_v4), name(ippool_name2_rev1_v6))) + rc = calicoctl("get ippool %s %s --export" % (name(ippool_name1_rev1_v4), name(ippool_name2_rev1_v6))) rc.assert_no_error() rc.assert_output_equals(ippool_name1_rev1_table + " \n\n" + ippool_name2_rev1_table) rcNoErr = rc # Get the 2 + one that does not exist - rc = calicoctl("get ippool %s %s %s" % (name(ippool_name1_rev1_v4), "blah", name(ippool_name2_rev1_v6))) + rc = calicoctl("get ippool %s %s %s --export" % (name(ippool_name1_rev1_v4), "blah", name(ippool_name2_rev1_v6))) rc.assert_error() rc.assert_output_equals(ippool_name1_rev1_table + " \n\n" + @@ -130,7 +133,7 @@ def test_get_delete_multiple_names(self): " \n\n" + "resource does not exist: IPPool(blah) with error: \n") - rc = calicoctl("get ippool %s %s %s" % (name(ippool_name1_rev1_v4), "blah", name(ippool_name2_rev1_v6)), + rc = calicoctl("get ippool %s %s %s --export" % (name(ippool_name1_rev1_v4), "blah", name(ippool_name2_rev1_v6)), only_stdout=True) # Check that the output with no errors and with some errors equal for @@ -396,21 +399,24 @@ def test_stdin(self): rc = calicoctl("create", data=globalnetworkpolicy_name1_rev1, format="json", load_as_stdin=True) rc.assert_no_error() rc = calicoctl("get globalnetworkpolicy %s -o json" % name(globalnetworkpolicy_name1_rev1)) - rc.assert_data(globalnetworkpolicy_name1_rev1, format="json") + res = add_tier_label(globalnetworkpolicy_name1_rev1) + rc.assert_data(res, format="json") # Use apply to update the GlobalNetworkPolicy and get the resource to check the # data was stored (using YAML input/output). rc = calicoctl("apply", data=globalnetworkpolicy_name1_rev2, format="yaml", load_as_stdin=True) rc.assert_no_error() rc = calicoctl("get globalnetworkpolicy %s -o yaml" % name(globalnetworkpolicy_name1_rev1)) - rc.assert_data(globalnetworkpolicy_name1_rev2, format="yaml") + res = add_tier_label(globalnetworkpolicy_name1_rev2) + rc.assert_data(res, format="yaml") # Use replace to update the GlobalNetworkPolicy and get the resource to check the # data was stored (using JSON input/output). rc = calicoctl("replace", data=globalnetworkpolicy_name1_rev1, format="json", load_as_stdin=True) rc.assert_no_error() rc = calicoctl("get globalnetworkpolicy %s -o json" % name(globalnetworkpolicy_name1_rev1)) - rc.assert_data(globalnetworkpolicy_name1_rev1, format="json") + res = add_tier_label(globalnetworkpolicy_name1_rev1) + rc.assert_data(res, format="json") # Use delete to delete the GlobalNetworkPolicy (using YAML input). rc = calicoctl("delete", data=globalnetworkpolicy_name1_rev1, format="yaml", load_as_stdin=True) @@ -433,7 +439,8 @@ def test_file_multi(self): # Get the resources using file based input. It should return the # same results. rc = calicoctl("get -o yaml", data=resources) - rc.assert_data(resources) + res = add_tier_label(resources) + rc.assert_data(res) # Use a get/list to get one of the resource types and an exact get to # get the other. Join them together and use it to delete the resource. @@ -441,7 +448,8 @@ def test_file_multi(self): # We use the data returned from the get since this should be able to # be used directly as input into the next command. rc = calicoctl("get globalnetworkpolicy %s -o yaml" % name(globalnetworkpolicy_name1_rev1)) - rc.assert_data(globalnetworkpolicy_name1_rev1) + res = add_tier_label(globalnetworkpolicy_name1_rev1) + rc.assert_data(res) gnp = rc.decoded rc = calicoctl("get workloadendpoints -o yaml --all-namespaces") @@ -494,11 +502,36 @@ def test_file_single_list(self): (hostendpoint_name1_rev1,), (bgppeer_name1_rev1_v4,), (node_name1_rev1,), + (tier_name1_rev1,), ]) + def test_non_namespaced(self, data): """ Test namespace is handled as expected for each non-namespaced resource type. """ + return self._test_non_namespaced(data) + + @parameterized.expand([ + (globalnetworkpolicy_tiered_name2_rev1,), + ]) + def test_non_namespaced_tiered(self, data): + """ + Test namespace is handled as expected for each non-namespaced resource type. + """ + self._create_admin_tier() + self._test_non_namespaced(data) + self._delete_admin_tier() + + def _create_admin_tier(self): + rc = calicoctl("create", data=tier_name1_rev1) + rc.assert_no_error() + + def _delete_admin_tier(self): + # Delete the resource + rc = calicoctl("delete", data=tier_name1_rev1) + rc.assert_no_error() + + def _test_non_namespaced(self, data): # Clone the data so that we can modify the metadata parms. data1 = copy.deepcopy(data) kind = data['kind'] @@ -600,6 +633,20 @@ def test_namespaced(self, data): """ Tests namespace is handled as expected for each namespaced resource type. """ + self._test_namespaced(data) + + @parameterized.expand([ + (networkpolicy_tiered_name2_rev1,), + ]) + def test_namespaced_tiered(self, data): + """ + Tests namespace is handled as expected for each namespaced resource type. + """ + self._create_admin_tier() + self._test_namespaced(data) + self._delete_admin_tier() + + def _test_namespaced(self, data): # Clone the data so that we can modify the metadata parms. data1 = copy.deepcopy(data) data2 = copy.deepcopy(data) @@ -626,6 +673,17 @@ def test_namespaced(self, data): data1['metadata']['name'] = "name1" data2['metadata']['name'] = "name2" data2['spec']['cidr'] = "10.10.1.0/24" + elif kind == "NetworkPolicy" or kind == "StagedNetworkPolicy" or kind == "StagedKubernetesNetworkPolicy": + tier = "default" + if 'tier' in data1['spec']: + tier = data1['spec']['tier'] + data1['metadata']['name'] = tier + "." + 'name1' + data1 = add_tier_label(data1) + tier = "default" + if 'tier' in data2['spec']: + tier = data2['spec']['tier'] + data2['metadata']['name'] = tier + "." + 'name2' + data2 = add_tier_label(data2) else: data1['metadata']['name'] = "name1" data2['metadata']['name'] = "name2" @@ -649,7 +707,7 @@ def test_namespaced(self, data): # Get the resource with name1 and default namespace. For a namespaced # resource this should match the modified data to default the # namespace. - rc = calicoctl("get %s %s --namespace default -o yaml" % (kind, data1['metadata']['name'])) + rc = calicoctl("get %s %s --namespace default -o yaml" % ((str(kind)).lower(), data1['metadata']['name'])) rc.assert_data(data1) if kind == "WorkloadEndpoint": @@ -701,6 +759,54 @@ def test_namespaced(self, data): rc = calicoctl("delete", data2) rc.assert_no_error() + @parameterized.expand([ + (globalnetworkpolicy_os_name1_rev1, False), + (networkpolicy_os_name1_rev1, True), + ]) + def test_os_compat(self, data, is_namespaced): + """ + Test policy CRUD commands with calico (open source) style manifests. + """ + # Clone the data so that we can modify the metadata parms. + data1 = copy.deepcopy(data) + + # Create the policy without a tier present in the name or spec. + rc = calicoctl("create", data=data1) + rc.assert_no_error() + + # On get, we expect name to be prefixed with the "default" tier name as + # well as have the tier field and value present in the spec. + # First we check with the name without tier in the name. + if is_namespaced: + rc = calicoctl("get %s %s --namespace default -o yaml" % (data['kind'], data['metadata']['name'])) + else: + rc = calicoctl("get %s %s -o yaml" % (data['kind'], data['metadata']['name'])) + data1['metadata']['name'] = 'default.' + data1['metadata']['name'] + data1['spec']['tier'] = 'default' + data1 = add_tier_label(data1) + rc.assert_data(data1) + + # Then we check with the tiered policy name. + if is_namespaced: + rc = calicoctl("get %s %s --namespace default -o yaml" % (data['kind'], data1['metadata']['name'])) + else: + rc = calicoctl("get %s %s -o yaml" % (data['kind'], data1['metadata']['name'])) + rc.assert_data(data1) + + # Deleting without a tiered policy name will delete the correct policy + if is_namespaced: + rc = calicoctl("delete %s %s --namespace default" % (data['kind'], data['metadata']['name'])) + else: + rc = calicoctl("delete %s %s" % (data['kind'], data['metadata']['name'])) + rc.assert_no_error() + + # And we re-check to make sure the deleted policy is not present. + if is_namespaced: + rc = calicoctl("get %s %s --namespace default -o yaml" % (data['kind'], data['metadata']['name'])) + else: + rc = calicoctl("get %s %s -o yaml" % (data['kind'], data['metadata']['name'])) + rc.assert_error(NOT_FOUND) + def test_bgpconfig(self): """ Test CRUD commands behave as expected on the BGP configuration resource: @@ -805,17 +911,6 @@ def test_clusterinfo(self): # Try to create a cluster info, should be rejected. rc = calicoctl("create", data=clusterinfo_name1_rev1) rc.assert_error(NOT_SUPPORTED) - rc = calicoctl("get clusterinfo %s -o yaml" % name(clusterinfo_name1_rev1)) - rc.assert_error(NOT_FOUND) - - # Replace the cluster information (with no resource version) - assert not supported. - rc = calicoctl("replace", data=clusterinfo_name1_rev2) - rc.assert_error(NOT_FOUND) - - # Apply an update to the cluster information and assert not found (we need the node to - # create it). - rc = calicoctl("apply", data=clusterinfo_name1_rev2) - rc.assert_error(NOT_SUPPORTED) # Delete the resource by name (i.e. without using a resource version) - assert not # supported. @@ -1017,6 +1112,31 @@ def test_disallow_crud_on_knp_defaults(self): rc.assert_error(text=NOT_SUPPORTED) rc.assert_error(text=KUBERNETES_NP) + def test_tier_list_order(self): + """ + Test that the list output for a tier is ordered by + the order field. + """ + # Create 3 tiers. + resources = [tier_name1_rev1, tier_name2_rev1, globalnetworkpolicy_name1_rev1] + rc = calicoctl ("create", data=resources) + rc.assert_no_error() + + # Get all the tiers. + rc = calicoctl("get tiers -o yaml") + rc.assert_no_error() + tierList = rc.decoded + + # Validate the tiers are ordered correctly. Default should have a value of 1M and should be placed last. + # adminnetworkpolicy has a value of 1K, and should be second one. + self.assertEqual(tierList['items'][0]['metadata']['name'], name(tier_name2_rev1)) + self.assertEqual(tierList['items'][1]['metadata']['name'], 'adminnetworkpolicy') + self.assertEqual(tierList['items'][2]['metadata']['name'], name(tier_name1_rev1)) + self.assertEqual(tierList['items'][3]['metadata']['name'], 'default') + + # Delete the resources + rc = calicoctl("delete", data=resources) + @parameterized.expand([ ('replace'), ('apply'), @@ -2380,6 +2500,9 @@ def check_only_default_profile_returned(self, testdata): ' resourceVersion: ' % (API_VERSION, API_VERSION, testdata['kind'], testdata['kind']) ) + def setUp(self): + super(InvalidData, self).setUp() + @parameterized.expand(testdata) def test_invalid_profiles_rejected(self, name, testdata, error): diff --git a/calicoctl/tests/st/calicoctl/test_migrate.py b/calicoctl/tests/st/calicoctl/test_migrate.py index 2da2f003145..c6f4bde3ef3 100644 --- a/calicoctl/tests/st/calicoctl/test_migrate.py +++ b/calicoctl/tests/st/calicoctl/test_migrate.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Tigera, Inc. All rights reserved. +# Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ from tests.st.utils.utils import log_and_run, calicoctl, \ API_VERSION, name, namespace, ERROR_CONFLICT, NOT_FOUND, NOT_NAMESPACED, \ SET_DEFAULT, NOT_SUPPORTED, KUBERNETES_NP, NOT_LOCKED, \ - NOT_KUBERNETES, NO_IPAM, writeyaml + NOT_KUBERNETES, NO_IPAM, writeyaml, add_tier_label from tests.st.utils.data import * logging.basicConfig(level=logging.DEBUG, format="%(message)s") @@ -89,9 +89,10 @@ def test_datastore_migrate(self): rc = calicoctl("create", data=globalnetworkpolicy_name1_rev1) rc.assert_no_error() rc = calicoctl("get globalnetworkpolicy %s -o yaml" % name(globalnetworkpolicy_name1_rev1)) - rc.assert_data(globalnetworkpolicy_name1_rev1) + res = add_tier_label(globalnetworkpolicy_name1_rev1) + rc.assert_data(res) rc = calicoctl("get globalnetworkpolicy -o yaml") - rc.assert_list("GlobalNetworkPolicy", [globalnetworkpolicy_name1_rev1]) + rc.assert_list("GlobalNetworkPolicy", [res]) # Create a Global Network set rc = calicoctl("create", data=globalnetworkset_name1_rev1) @@ -113,14 +114,16 @@ def test_datastore_migrate(self): rc = calicoctl("create", data=networkpolicy_name1_rev1) rc.assert_no_error() rc = calicoctl("get networkpolicy %s -o yaml" % name(networkpolicy_name1_rev1)) - rc.assert_data(networkpolicy_name1_rev1) + res = add_tier_label(networkpolicy_name1_rev1) + rc.assert_data(res) rc.assert_no_error() # Create namespaced Network policy rc = calicoctl("create", data=networkpolicy_name3_rev1) rc.assert_no_error() rc = calicoctl("get networkpolicy %s -n %s -o yaml" % (name(networkpolicy_name3_rev1), namespace(networkpolicy_name3_rev1))) - rc.assert_data(networkpolicy_name3_rev1) + res = add_tier_label(networkpolicy_name3_rev1) + rc.assert_data(res) rc.assert_no_error() # Create NetworkSets @@ -150,6 +153,14 @@ def test_datastore_migrate(self): rc = calicoctl("get node %s -o yaml" % name(node_name5_rev1)) rc.assert_data(node_name5_rev1) + # Create an IP reservation. + rc = calicoctl("create", data=ipresv_name1_rev1_v4) + rc.assert_no_error() + + # Create a BGPFilter. + rc = calicoctl("create", data=bgpfilter_name1_rev1) + rc.assert_no_error() + # TODO: Pull code or modify tests to create IPAM objects for this test # since they cannot be created via calicoctl. @@ -196,6 +207,10 @@ def test_datastore_migrate(self): rc.assert_no_error() rc = calicoctl("delete node %s" % name(node_name5_rev1)) rc.assert_no_error() + rc = calicoctl("delete ipreservation %s" % name(ipresv_name1_rev1_v4)) + rc.assert_no_error() + rc = calicoctl("delete bgpfilter %s" % name(bgpfilter_name1_rev1)) + rc.assert_no_error() # Attempt and fail to import the data into an etcd datastore rc = calicoctl("datastore migrate import -f /tmp/test-migration") @@ -225,15 +240,18 @@ def test_datastore_migrate(self): rc = calicoctl("get felixconfig %s -o yaml" % name(felixconfig_name3_rev1), kdd=True) rc.assert_no_error() rc = calicoctl("get globalnetworkpolicy %s -o yaml" % name(globalnetworkpolicy_name1_rev1), kdd=True) - rc.assert_data(globalnetworkpolicy_name1_rev1) + res = add_tier_label(globalnetworkpolicy_name1_rev1) + rc.assert_data(res) rc = calicoctl("get globalnetworkset %s -o yaml" % name(globalnetworkset_name1_rev1), kdd=True) rc.assert_data(globalnetworkset_name1_rev1) rc = calicoctl("get hostendpoint %s -o yaml" % name(hostendpoint_name1_rev1), kdd=True) rc.assert_data(hostendpoint_name1_rev1) rc = calicoctl("get networkpolicy %s -o yaml" % name(networkpolicy_name1_rev1), kdd=True) - rc.assert_data(networkpolicy_name1_rev1) + res = add_tier_label(networkpolicy_name1_rev1) + rc.assert_data(res) rc = calicoctl("get networkpolicy %s -n %s -o yaml" % (name(networkpolicy_name3_rev1), namespace(networkpolicy_name3_rev1)), kdd=True) - rc.assert_data(networkpolicy_name3_rev1) + res = add_tier_label(networkpolicy_name3_rev1) + rc.assert_data(res) rc = calicoctl("get networkset %s -o yaml" % name(networkset_name1_rev1), kdd=True) rc.assert_no_error() rc = calicoctl("get networkset %s -n %s -o yaml" % (name(networkset_name2_rev1), namespace(networkset_name2_rev1)), kdd=True) @@ -244,6 +262,10 @@ def test_datastore_migrate(self): rc.assert_error(text=NOT_FOUND) rc = calicoctl("get clusterinfo %s -o yaml" % name(clusterinfo_name1_rev1), kdd=True) rc.assert_no_error() + rc = calicoctl("get ipreservation %s -o yaml" % name(ipresv_name1_rev1_v4), kdd=True) + rc.assert_no_error() + rc = calicoctl("get bgpfilter %s -o yaml" % name(bgpfilter_name1_rev1), kdd=True) + rc.assert_no_error() # Unlock the datastore rc = calicoctl("datastore migrate unlock", kdd=True) @@ -276,3 +298,7 @@ def test_datastore_migrate(self): rc.assert_no_error() rc = calicoctl("delete networkset %s -n %s" % (name(networkset_name2_rev1), namespace(networkset_name2_rev1)), kdd=True) rc.assert_no_error() + rc = calicoctl("delete ipreservation %s" % name(ipresv_name1_rev1_v4), kdd=True) + rc.assert_no_error() + rc = calicoctl("delete bgpfilter %s" % name(bgpfilter_name1_rev1), kdd=True) + rc.assert_no_error() diff --git a/calicoctl/tests/st/utils/data.py b/calicoctl/tests/st/utils/data.py index b0b0cf4fa54..1484a92b716 100644 --- a/calicoctl/tests/st/utils/data.py +++ b/calicoctl/tests/st/utils/data.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Tigera, Inc. All rights reserved. +# Copyright (c) 2015-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ for i in xrange(10000): many_nets.append("10.%s.%s.0/28" % (i >> 8, i % 256)) + # # IPPools # @@ -224,6 +225,27 @@ } } +# +# BGP filters +# + +bgpfilter_name1_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'BGPFilter', + 'metadata': { + 'name': 'bgpfilter-name1' + }, + 'spec': { + 'exportv4': [ + { + 'cidr': '10.0.0.0/16', + 'matchOperator': 'Equal', + 'action': 'Accept', + }, + ], + } +} + # # BGPPeers # @@ -303,6 +325,32 @@ } }] +# +# Tier1 +# + +tier_name1_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'Tier', + 'metadata': { + 'name': 'admin', + }, + 'spec': { + 'Order': 10000, + }, +} + +tier_name2_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'Tier', + 'metadata': { + 'name': 'before', + }, + 'spec': { + 'Order': 100, + }, +} + # # Network Policy # @@ -310,10 +358,11 @@ 'apiVersion': API_VERSION, 'kind': 'NetworkPolicy', 'metadata': { - 'name': 'policy-mypolicy1', + 'name': 'default.policy-mypolicy1', 'namespace': 'default' }, 'spec': { + 'tier': 'default', 'order': 100, 'selector': "type=='database'", 'types': ['Ingress', 'Egress'], @@ -359,6 +408,7 @@ 'namespace': 'default' }, 'spec': { + 'tier': "default", 'order': 100000, 'selector': "type=='sql'", 'types': ['Ingress', 'Egress'], @@ -381,7 +431,7 @@ 'apiVersion': API_VERSION, 'kind': 'NetworkPolicy', 'metadata': { - 'name': 'policy-mypolicy2', + 'name': 'default.policy-mypolicy2', 'namespace': 'default', 'generateName': 'test-policy-', 'deletionTimestamp': '2006-01-02T15:04:07Z', @@ -403,6 +453,7 @@ 'creationTimestamp': '2006-01-02T15:04:05Z', }, 'spec': { + 'tier': "default", 'order': 100000, 'selector': "type=='sql'", 'types': ['Ingress', 'Egress'], @@ -421,12 +472,39 @@ } } -networkpolicy_name3_rev1 = { +networkpolicy_tiered_name2_rev1 = { 'apiVersion': API_VERSION, 'kind': 'NetworkPolicy', 'metadata': { - 'name': 'policy-mypolicy3', - 'namespace': 'test', + 'name': 'admin.mypolicy2', + 'namespace': 'default' + }, + 'spec': { + 'tier': 'admin', + 'order': 100000, + 'selector': "type=='sql'", + 'types': ['Ingress', 'Egress'], + 'egress': [ + { + 'action': 'Deny', + 'protocol': 'TCP', + }, + ], + 'ingress': [ + { + 'action': 'Allow', + 'protocol': 'UDP', + }, + ], + } +} + +networkpolicy_os_name1_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'NetworkPolicy', + 'metadata': { + 'name': 'os-policy-mypolicy1', + 'namespace': 'default' }, 'spec': { 'order': 100, @@ -473,9 +551,10 @@ 'apiVersion': API_VERSION, 'kind': 'GlobalNetworkPolicy', 'metadata': { - 'name': 'policy-mypolicy1', + 'name': 'default.policy-mypolicy1', }, 'spec': { + 'tier': "default", 'order': 100, 'selector': "type=='database'", 'types': ['Ingress', 'Egress'], @@ -517,9 +596,10 @@ 'apiVersion': API_VERSION, 'kind': 'GlobalNetworkPolicy', 'metadata': { - 'name': 'policy-mypolicy1', + 'name': 'default.policy-mypolicy1', }, 'spec': { + 'tier': "default", 'order': 100000, 'selector': "type=='sql'", 'doNotTrack': True, @@ -540,6 +620,124 @@ } } +globalnetworkpolicy_tiered_name2_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'GlobalNetworkPolicy', + 'metadata': { + 'name': 'admin.mypolicy2', + }, + 'spec': { + 'tier': 'admin', + 'order': 100000, + 'selector': "type=='sql'", + 'doNotTrack': True, + 'applyOnForward': True, + 'types': ['Ingress', 'Egress'], + 'egress': [ + { + 'action': 'Deny', + 'protocol': 'TCP', + }, + ], + 'ingress': [ + { + 'action': 'Allow', + 'protocol': 'UDP', + }, + ], + } +} + +globalnetworkpolicy_os_name1_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'GlobalNetworkPolicy', + 'metadata': { + 'name': 'os-policy-mypolicy1', + }, + 'spec': { + 'order': 100, + 'selector': "type=='database'", + 'types': ['Ingress', 'Egress'], + 'egress': [ + { + 'action': 'Allow', + 'source': { + 'selector': "type=='application'"}, + }, + ], + 'ingress': [ + { + 'ipVersion': 4, + 'action': 'Deny', + 'destination': { + 'notNets': ['10.3.0.0/16'], + 'notPorts': ['110:1050'], + 'notSelector': "type=='apples'", + 'nets': ['10.2.0.0/16'], + 'ports': ['100:200'], + 'selector': "type=='application'", + }, + 'protocol': 'TCP', + 'source': { + 'notNets': ['10.1.0.0/16'], + 'notPorts': [1050], + 'notSelector': "type=='database'", + 'nets': ['10.0.0.0/16'], + 'ports': [1234, '10:1024'], + 'selector': "type=='application'", + 'namespaceSelector': 'has(role)', + } + } + ], + } +} + +networkpolicy_name3_rev1 = { + 'apiVersion': API_VERSION, + 'kind': 'NetworkPolicy', + 'metadata': { + 'name': 'default.policy-mypolicy3', + 'namespace': 'test', + }, + 'spec': { + 'tier': "default", + 'order': 100, + 'selector': "type=='database'", + 'types': ['Ingress', 'Egress'], + 'egress': [ + { + 'action': 'Allow', + 'source': { + 'selector': "type=='application'"}, + }, + ], + 'ingress': [ + { + 'ipVersion': 4, + 'action': 'Deny', + 'destination': { + 'notNets': ['10.3.0.0/16'], + 'notPorts': ['110:1050'], + 'notSelector': "type=='apples'", + 'nets': ['10.2.0.0/16'], + 'ports': ['100:200'], + 'selector': "type=='application'", + }, + 'protocol': 'TCP', + 'source': { + 'notNets': ['10.1.0.0/16'], + 'notPorts': [1050], + 'notSelector': "type=='database'", + 'nets': ['10.0.0.0/16'], + 'ports': [1234, '10:1024'], + 'selector': "type=='application'", + 'namespaceSelector': 'has(role)', + } + } + ], + } +} + # # Global network sets @@ -557,7 +755,7 @@ "11.0.0.0/16", "feed:beef::1", "dead:beef::96", - ] + ], } } @@ -1168,7 +1366,6 @@ } } -# # KubeControllersConfiguration # kubecontrollersconfig_name1_rev1 = { diff --git a/calicoctl/tests/st/utils/utils.py b/calicoctl/tests/st/utils/utils.py index 38f2df5ad23..74fee5b889a 100644 --- a/calicoctl/tests/st/utils/utils.py +++ b/calicoctl/tests/st/utils/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2016 Tigera, Inc. All rights reserved. +# Copyright (c) 2015-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -318,6 +318,29 @@ def clean_elem(elem, extra_keys): clean_elem(new, extra_keys_to_remove) return new +def add_tier_label(data): + """ + Convenience method for auto-adding the `projectcalico.org/tier`. + """ + new = copy.deepcopy(data) + + def add_label(elem): + if isinstance(elem, list): + for i in elem: + add_label(i) + if isinstance(elem, dict): + if elem['kind'] not in ['NetworkPolicy', 'GlobalNetworkPolicy']: + return + tier = 'default' + if 'tier' in elem['spec']: + tier = elem['spec']['tier'] + if 'labels' not in elem['metadata']: + elem['metadata']['labels'] = {} + elem['metadata']['labels']['projectcalico.org/tier'] = tier + + add_label(new) + return new + def decode_json_yaml(value): try: @@ -522,13 +545,23 @@ def name(data): """ return data['metadata']['name'] +def kind(data): + """ + Returns the kind of the resource in the supplied data + Args: + data: A dictionary containing the resource. + + Returns: The resource kind. + """ + return data['kind'] + def namespace(data): """ Returns the namespace of the resource in the supplied data Args: data: A dictionary containing the resource. - Returns: The resource name. + Returns: The resource namespace. """ return data['metadata']['namespace'] diff --git a/calicoctl/tests/st/utils/v1_data.py b/calicoctl/tests/st/utils/v1_data.py index 341077cc099..601f56313d9 100644 --- a/calicoctl/tests/st/utils/v1_data.py +++ b/calicoctl/tests/st/utils/v1_data.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Tigera, Inc. All rights reserved. +# Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -153,27 +153,33 @@ data['policy_tame'] = { 'apiVersion': 'v1', 'kind': 'policy', - 'metadata': {'name': 'allow-tcp-6379'}, - 'spec': {'egress': [{'action': 'allow'}], - 'ingress': [{'action': 'allow', - 'destination': {'ports': [6379]}, - 'protocol': 'tcp', - 'source': {'selector': "role == 'frontend'"}}], - 'selector': "role == 'database'", - 'types': ['ingress', 'egress']} + 'metadata': { + 'name': 'default.allow-tcp-6379' + }, + 'spec': { + 'egress': [{'action': 'allow'}], + 'ingress': [{'action': 'allow', + 'destination': {'ports': [6379]}, + 'protocol': 'tcp', + 'source': {'selector': "role == 'frontend'"}}], + 'selector': "role == 'database'", + 'types': ['ingress', 'egress'] + } } data['policy_long_name'] = { 'apiVersion': 'v1', 'kind': 'policy', 'metadata': { - 'name': '-Mary_had-A-Little___Lamb--Whose---Fleece-Was-White.As.Snow...She-Also-Had_an-Evil-PolicyName_in_order_to.break.upgrade-code2016'}, - 'spec': {'egress': [{'action': 'allow'}], - 'ingress': [{'action': 'allow', - 'destination': {'ports': [6379]}, - 'protocol': 'tcp', - 'source': {'nets': ['192.168.0.1/32']}}], - 'selector': "role == 'database'", - 'types': ['ingress', 'egress']} + 'name': 'Mary_had-A-Little___Lamb--Whose---Fleece-Was-White.As.Snow...She-Also-Had_an-Evil-PolicyName_in_order_to.break.upgrade-code2016' + }, + 'spec': { + 'egress': [{'action': 'allow'}], + 'ingress': [{'action': 'allow', + 'destination': {'ports': [6379]}, + 'protocol': 'tcp', + 'source': {'nets': ['192.168.0.1/32']}}], + 'selector': "role == 'database'", + 'types': ['ingress', 'egress']} } data['profile_tame'] = { 'apiVersion': 'v1', @@ -258,7 +264,10 @@ data['policy_big'] = { 'apiVersion': 'v1', 'kind': 'policy', - 'metadata': {'annotations': {'aname': 'avalue'}, 'name': 'allow-tcp-6379'}, + 'metadata': { + 'annotations': {'aname': 'avalue'}, + 'name': 'default.allow-tcp-6379' + }, 'spec': {'egress': [{'action': 'allow', 'icmp': {'code': 25, 'type': 25}, 'protocol': 'icmp'}], @@ -467,7 +476,7 @@ data['prednat_policy'] = { 'apiVersion': 'v1', 'kind': 'policy', - 'metadata': {'name': 'allow-cluster-internal-ingress'}, + 'metadata': {'name': 'default.allow-cluster-internal-ingress'}, 'spec': {'ingress': [{'action': 'allow', 'source': {'nets': ['10.240.0.0/16', '192.168.0.0/16']}}], diff --git a/charts/calico/templates/calico-kube-controllers-rbac.yaml b/charts/calico/templates/calico-kube-controllers-rbac.yaml index b099a93bf5b..5a7398c488e 100644 --- a/charts/calico/templates/calico-kube-controllers-rbac.yaml +++ b/charts/calico/templates/calico-kube-controllers-rbac.yaml @@ -75,6 +75,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list diff --git a/charts/calico/templates/calico-node-rbac.yaml b/charts/calico/templates/calico-node-rbac.yaml index c3fc84c35f9..d2c139a61ca 100644 --- a/charts/calico/templates/calico-node-rbac.yaml +++ b/charts/calico/templates/calico-node-rbac.yaml @@ -68,6 +68,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -103,6 +110,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/charts/calico/values.yaml b/charts/calico/values.yaml index 0317c875be1..b60c0667084 100644 --- a/charts/calico/values.yaml +++ b/charts/calico/values.yaml @@ -14,7 +14,7 @@ kubeControllers: image: docker.io/calico/kube-controllers flannel: image: docker.io/flannel/flannel - tag: v0.24.3 + tag: v0.24.4 flannelMigration: image: docker.io/calico/flannel-migration dikastes: diff --git a/charts/tigera-operator/crds/operator.tigera.io_apiservers_crd.yaml b/charts/tigera-operator/crds/operator.tigera.io_apiservers_crd.yaml index 8bbbb171bf8..e32c61d1a0e 100644 --- a/charts/tigera-operator/crds/operator.tigera.io_apiservers_crd.yaml +++ b/charts/tigera-operator/crds/operator.tigera.io_apiservers_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: apiservers.operator.tigera.io spec: group: operator.tigera.io @@ -16,19 +16,24 @@ spec: - name: v1 schema: openAPIV3Schema: - description: APIServer installs the Tigera API server and related resources. - At most one instance of this resource is supported. It must be named "default" - or "tigera-secure". + description: |- + APIServer installs the Tigera API server and related resources. At most one instance + of this resource is supported. It must be named "default" or "tigera-secure". properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -36,10 +41,10 @@ spec: description: Specification of the desired state for the Tigera API server. properties: apiServerDeployment: - description: APIServerDeployment configures the calico-apiserver (or - tigera-apiserver in Enterprise) Deployment. If used in conjunction - with ControlPlaneNodeSelector or ControlPlaneTolerations, then these - overrides take precedence. + description: |- + APIServerDeployment configures the calico-apiserver (or tigera-apiserver in Enterprise) Deployment. If + used in conjunction with ControlPlaneNodeSelector or ControlPlaneTolerations, then these overrides + take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -48,31 +53,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the API server Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the API server Deployment. If omitted, - the API server Deployment will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -82,65 +85,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the API server Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the API server pods. If specified, this - overrides any affinity that may be set on the API - server Deployment. If omitted, the API server Deployment - will use its default value for affinity. WARNING: - Please note that this field will override the default - API server Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the API server pods. + If specified, this overrides any affinity that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default API server Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -150,9 +144,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -161,27 +154,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -194,9 +177,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -205,27 +187,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -248,31 +220,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -281,27 +250,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -314,9 +273,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -325,27 +283,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -368,21 +316,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -404,10 +347,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -416,24 +357,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -446,30 +378,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -477,10 +399,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -489,24 +409,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -519,51 +430,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -573,28 +469,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -605,11 +495,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -617,23 +505,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -645,39 +526,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -685,23 +556,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -713,41 +577,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -760,21 +612,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -796,10 +643,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -808,24 +653,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -838,30 +674,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -869,10 +695,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -881,24 +705,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -911,51 +726,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -965,28 +765,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -997,11 +791,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1009,23 +801,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1037,39 +822,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1077,23 +852,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1105,41 +873,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -1148,50 +904,44 @@ spec: type: object type: object containers: - description: Containers is a list of API server containers. - If specified, this overrides the specified API server - Deployment containers. If omitted, the API server - Deployment will use its default values for its containers. + description: |- + Containers is a list of API server containers. + If specified, this overrides the specified API server Deployment containers. + If omitted, the API server Deployment will use its default values for its containers. items: description: APIServerDeploymentContainer is an API server Deployment container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment container by name. - Supported values are: calico-apiserver, tigera-queryserver' + description: |- + Name is an enum which identifies the API server Deployment container by name. + Supported values are: calico-apiserver, tigera-queryserver enum: - calico-apiserver - tigera-queryserver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - container's resources. If omitted, the API - server Deployment will use its default value - for this container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment container's resources. + If omitted, the API server Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1208,9 +958,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1219,13 +969,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1233,48 +981,42 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of API server - init containers. If specified, this overrides the - specified API server Deployment init containers. - If omitted, the API server Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of API server init containers. + If specified, this overrides the specified API server Deployment init containers. + If omitted, the API server Deployment will use its default values for its init containers. items: description: APIServerDeploymentInitContainer is an API server Deployment init container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment init container by - name. Supported values are: calico-apiserver-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the API server Deployment init container by name. + Supported values are: calico-apiserver-certs-key-cert-provisioner enum: - calico-apiserver-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - init container's resources. If omitted, the - API server Deployment will use its default - value for this init container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment init container's resources. + If omitted, the API server Deployment will use its default value for this init container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1291,9 +1033,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1302,13 +1044,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1318,88 +1058,72 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the API server pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the API server Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the API server Deployment and each of - this field''s key/value pairs are added to the API - server Deployment nodeSelector provided the key - does not already exist in the object''s nodeSelector. - If omitted, the API server Deployment will use its - default value for nodeSelector. WARNING: Please - note that this field will modify the default API - server Deployment nodeSelector.' + description: |- + NodeSelector is the API server pod's scheduling constraints. + If specified, each of the key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the API server Deployment + and each of this field's key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the API server Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default API server Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the API server pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the API server Deployment. If - omitted, the API server Deployment will use its - default value for tolerations. WARNING: Please note - that this field will override the default API server - Deployment tolerations.' + description: |- + Tolerations is the API server pod's tolerations. + If specified, this overrides any tolerations that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default API server Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -1407,30 +1131,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1442,158 +1161,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -1610,47 +1295,47 @@ spec: description: Most recently observed status for the Tigera API server. properties: conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -1664,11 +1349,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string diff --git a/charts/tigera-operator/crds/operator.tigera.io_imagesets_crd.yaml b/charts/tigera-operator/crds/operator.tigera.io_imagesets_crd.yaml index 1ff5e5eb9ac..bf0604f032d 100644 --- a/charts/tigera-operator/crds/operator.tigera.io_imagesets_crd.yaml +++ b/charts/tigera-operator/crds/operator.tigera.io_imagesets_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: imagesets.operator.tigera.io spec: group: operator.tigera.io @@ -16,23 +16,28 @@ spec: - name: v1 schema: openAPIV3Schema: - description: ImageSet is used to specify image digests for the images that - the operator deploys. The name of the ImageSet is expected to be in the - format `-`. The `variant` used is `enterprise` if the - InstallationSpec Variant is `TigeraSecureEnterprise` otherwise it is `calico`. - The `release` must match the version of the variant that the operator is - built to deploy, this version can be obtained by passing the `--version` - flag to the operator binary. + description: |- + ImageSet is used to specify image digests for the images that the operator deploys. + The name of the ImageSet is expected to be in the format `-`. + The `variant` used is `enterprise` if the InstallationSpec Variant is + `TigeraSecureEnterprise` otherwise it is `calico`. + The `release` must match the version of the variant that the operator is built to deploy, + this version can be obtained by passing the `--version` flag to the operator binary. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -40,21 +45,22 @@ spec: description: ImageSetSpec defines the desired state of ImageSet. properties: images: - description: Images is the list of images to use digests. All images - that the operator will deploy must be specified. + description: |- + Images is the list of images to use digests. All images that the operator will deploy + must be specified. items: properties: digest: - description: Digest is the image identifier that will be used - for the Image. The field should not include a leading `@` - and must be prefixed with `sha256:`. + description: |- + Digest is the image identifier that will be used for the Image. + The field should not include a leading `@` and must be prefixed with `sha256:`. type: string image: - description: Image is an image that the operator deploys and - instead of using the built in tag the operator will use the - Digest for the image identifier. The value should be the image - name without registry or tag or digest. For the image `docker.io/calico/node:v3.17.1` - it should be represented as `calico/node` + description: |- + Image is an image that the operator deploys and instead of using the built in tag + the operator will use the Digest for the image identifier. + The value should be the image name without registry or tag or digest. + For the image `docker.io/calico/node:v3.17.1` it should be represented as `calico/node` type: string required: - digest diff --git a/charts/tigera-operator/crds/operator.tigera.io_installations_crd.yaml b/charts/tigera-operator/crds/operator.tigera.io_installations_crd.yaml index cd8c6e0a3f5..a90bc6b52b0 100644 --- a/charts/tigera-operator/crds/operator.tigera.io_installations_crd.yaml +++ b/charts/tigera-operator/crds/operator.tigera.io_installations_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: installations.operator.tigera.io spec: group: operator.tigera.io @@ -16,20 +16,25 @@ spec: - name: v1 schema: openAPIV3Schema: - description: Installation configures an installation of Calico or Calico Enterprise. - At most one instance of this resource is supported. It must be named "default". - The Installation API installs core networking and network policy components, - and provides general install-time configuration. + description: |- + Installation configures an installation of Calico or Calico Enterprise. At most one instance + of this resource is supported. It must be named "default". The Installation API installs core networking + and network policy components, and provides general install-time configuration. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -38,9 +43,9 @@ spec: Enterprise installation. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -49,18 +54,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -68,13 +73,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-kube-controllers Deployment. - If omitted, the calico-kube-controllers Deployment will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -84,25 +87,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -110,41 +113,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-kube-controllers pods. If specified, - this overrides any affinity that may be set on the - calico-kube-controllers Deployment. If omitted, - the calico-kube-controllers Deployment will use - its default value for affinity. WARNING: Please - note that this field will override the default calico-kube-controllers - Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -154,9 +147,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -165,27 +157,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -198,9 +180,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -209,27 +190,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -252,31 +223,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -285,27 +253,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -318,9 +276,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -329,27 +286,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -372,21 +319,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -408,10 +350,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -420,24 +360,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -450,30 +381,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -481,10 +402,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -493,24 +412,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -523,51 +433,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -577,28 +472,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -609,11 +498,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -621,23 +508,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -649,39 +529,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -689,23 +559,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -717,41 +580,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -764,21 +615,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -800,10 +646,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -812,24 +656,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -842,30 +677,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -873,10 +698,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -885,24 +708,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -915,51 +729,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -969,28 +768,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -1001,11 +794,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1013,23 +804,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1041,39 +825,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1081,23 +855,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1109,41 +876,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -1152,51 +907,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the specified - calico-kube-controllers Deployment containers. If - omitted, the calico-kube-controllers Deployment - will use its default values for its containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment container - by name. Supported values are: calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment will - use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1213,9 +961,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1224,13 +972,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1240,71 +986,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-kube-controllers - Deployment nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - used in conjunction with ControlPlaneNodeSelector, - that nodeSelector is set on the calico-kube-controllers - Deployment and each of this field''s key/value pairs - are added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-kube-controllers - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -1324,38 +1055,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip forwarding - will be enabled for containers in the CNI configuration. Default: - Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the Calico - CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create if - none exist. At most one IP pool of each address family may be - specified. If omitted, a single pool will be configured if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will be - used for. If not specified or empty, defaults to ["Tunnel", - "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the main - IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -1364,13 +1096,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -1383,15 +1117,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector that - will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -1399,60 +1135,64 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane used - for Linux nodes. In particular, it causes the operator to add - required mounts and environment variables for the particular - dataplane. If not specified, iptables mode is used. Default: - Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods from - running containers until their policy has been programmed in - the dataplane. The specified delay defines the maximum amount - of time that the Calico CNI plugin will wait for policy to be - programmed. \n Only applies to pods created on Linux nodes. - \n * A value of 0 disables pod startup delays. \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to use - on the pod network. If not specified, Calico will perform MTU - auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -1465,30 +1205,32 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -1501,8 +1243,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -1523,21 +1266,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the particular - dataplane. If not specified, it is disabled and the operator - will not render the Calico Windows nodes daemonset. Default: - Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, then - these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -1546,31 +1288,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the calico-node DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node DaemonSet. If omitted, - the calico-node DaemonSet will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -1580,65 +1320,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node pods. If specified, this - overrides any affinity that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -1648,9 +1379,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1659,27 +1389,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1692,9 +1412,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1703,27 +1422,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1746,31 +1455,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1779,27 +1485,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1812,9 +1508,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1823,27 +1518,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1866,21 +1551,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -1902,10 +1582,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1914,24 +1592,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -1944,30 +1613,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -1975,10 +1634,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1987,24 +1644,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2017,51 +1665,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -2071,28 +1704,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -2103,11 +1730,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2115,23 +1740,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2143,39 +1761,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2183,23 +1791,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2211,41 +1812,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -2258,21 +1847,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -2294,10 +1878,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2306,24 +1888,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2336,30 +1909,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -2367,10 +1930,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2379,24 +1940,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2409,51 +1961,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -2463,28 +2000,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -2495,11 +2026,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2507,23 +2036,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2535,39 +2057,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2575,23 +2087,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2603,41 +2108,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -2646,49 +2139,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node containers. - If specified, this overrides the specified calico-node - DaemonSet containers. If omitted, the calico-node - DaemonSet will use its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by name. - Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - container's resources. If omitted, the calico-node - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -2705,9 +2192,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2716,13 +2203,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -2730,21 +2215,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides the - specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use its - default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container by - name. Supported values are: install-cni, hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -2754,33 +2236,27 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - init container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. If used - in conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -2797,9 +2273,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2808,13 +2284,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -2824,65 +2298,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-node DaemonSet - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-node - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use its - default value for tolerations. WARNING: Please note - that this field will override the default calico-node - DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -2901,18 +2363,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -2920,13 +2382,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet will use its - default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -2936,25 +2396,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -2962,40 +2422,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node-windows pods. If specified, - this overrides any affinity that may be set on the - calico-node-windows DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -3005,9 +2456,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3016,27 +2466,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3049,9 +2489,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3060,27 +2499,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3103,31 +2532,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3136,27 +2562,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3169,9 +2585,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3180,27 +2595,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3223,21 +2628,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -3259,10 +2659,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3271,24 +2669,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3301,30 +2690,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -3332,10 +2711,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3344,24 +2721,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3374,51 +2742,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -3428,28 +2781,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -3460,11 +2807,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3472,23 +2817,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3500,39 +2838,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3540,23 +2868,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3568,41 +2889,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -3615,21 +2924,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -3651,10 +2955,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3663,24 +2965,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3693,30 +2986,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -3724,10 +3007,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3736,24 +3017,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3766,51 +3038,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -3820,28 +3077,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -3852,11 +3103,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3864,23 +3113,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3892,39 +3134,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3932,23 +3164,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3960,41 +3185,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -4003,50 +3216,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the specified - calico-node-windows DaemonSet containers. If omitted, - the calico-node-windows DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - container's resources. If omitted, the calico-node-windows - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -4063,9 +3269,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4074,13 +3280,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -4088,21 +3292,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides the - specified calico-node-windows DaemonSet init containers. - If omitted, the calico-node-windows DaemonSet will - use its default values for its init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init container - by name. Supported values are: install-cni;hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -4112,34 +3313,27 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - init container's resources. If omitted, the - calico-node-windows DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -4156,9 +3350,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4167,13 +3361,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -4183,66 +3375,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-node-windows - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-node-windows DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for tolerations. WARNING: - Please note that this field will override the default - calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -4251,9 +3430,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated - and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -4262,18 +3441,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -4281,13 +3460,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-windows-upgrade DaemonSet. - If omitted, the calico-windows-upgrade DaemonSet will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -4297,25 +3474,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -4323,41 +3500,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-windows-upgrade pods. If specified, - this overrides any affinity that may be set on the - calico-windows-upgrade DaemonSet. If omitted, the - calico-windows-upgrade DaemonSet will use its default - value for affinity. WARNING: Please note that this - field will override the default calico-windows-upgrade - DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -4367,9 +3534,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4378,27 +3544,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4411,9 +3567,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4422,27 +3577,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4465,31 +3610,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4498,27 +3640,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4531,9 +3663,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4542,27 +3673,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4585,21 +3706,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -4621,10 +3737,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4633,24 +3747,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4663,30 +3768,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -4694,10 +3789,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4706,24 +3799,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4736,51 +3820,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -4790,28 +3859,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -4822,11 +3885,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -4834,23 +3895,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4862,39 +3916,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -4902,23 +3946,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4930,41 +3967,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -4977,21 +4002,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -5013,10 +4033,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5025,24 +4043,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5055,30 +4064,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -5086,10 +4085,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5098,24 +4095,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5128,51 +4116,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -5182,28 +4155,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -5214,11 +4181,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5226,23 +4191,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5254,39 +4212,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5294,23 +4242,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5322,41 +4263,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -5365,11 +4294,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the specified - calico-windows-upgrade DaemonSet containers. If - omitted, the calico-windows-upgrade DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -5382,32 +4310,26 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5424,9 +4346,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5435,13 +4357,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5451,66 +4371,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-windows-upgrade - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-windows-upgrade DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-windows-upgrade DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -5519,10 +4426,10 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a CertificateSigningRequest - to the certificates.k8s.io/v1beta1 API in order to obtain TLS certificates. - This feature requires that you bring your own CSR signing and approval - process, otherwise pods will be stuck during initialization. + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise + pods will be stuck during initialization. properties: caCert: description: Certificate of the authority that signs the CertificateSigningRequests @@ -5530,9 +4437,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate a - key pair that is associated with the X.509 certificate request. - Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -5543,8 +4450,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature of - the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -5555,9 +4463,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to accommodate - for clusters with multiple signers. Must be formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -5567,21 +4476,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management that - will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For CNI - Plugin Calico, this field defaults to Calico. * For CNI - Plugin GKE, this field defaults to HostLocal. * For CNI - Plugin AzureVNET, this field defaults to AzureVNET. * For - CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only if the - CNI plugin is set to Calico, for all other values of the - CNI plugin the plugin binaries and CNI config is a dependency - that is expected to be installed separately. \n Default: - Calico" + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. + * For CNI Plugin AzureVNET, this field defaults to AzureVNET. + * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -5592,18 +4501,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in the - Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider AKS, - this field defaults to AzureVNET. * For KubernetesProvider EKS, - this field defaults to AmazonVPC. * If aws-node daemonset exists - in kube-system when the Installation resource is created, this - field defaults to AmazonVPC. * For all other cases this field - defaults to Calico. \n For the value Calico, the CNI plugin - binaries and CNI config will be installed as part of deployment, - for all other values the CNI plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -5614,14 +4522,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used to - customize the resource requirements for each component. Node, Typha, - and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config fields - in Installation.Spec instead. The ComponentResource struct associates - a ResourceRequirements with a component by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the component @@ -5635,18 +4543,19 @@ spec: and requests for compute resources such as cpu and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only - be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where this - field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5663,8 +4572,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5673,11 +4583,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5688,55 +4598,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control plane - nodes on which to run Calico components. This is globally applied - to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of the - control plane core components will be deployed. This field applies - to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which are - then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match all - values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to the - value. Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod - can tolerate all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of time - the toleration (which must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. By default, it - is not set, which means tolerate the taint forever (do not - evict). Zero and negative values will be treated as 0 (evict - immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -5751,18 +4660,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -5770,13 +4679,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use its default - value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -5786,65 +4693,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the csi-node-driver DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the csi-node-driver pods. If specified, - this overrides any affinity that may be set on the - csi-node-driver DaemonSet. If omitted, the csi-node-driver - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -5854,9 +4752,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5865,27 +4762,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5898,9 +4785,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5909,27 +4795,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5952,31 +4828,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5985,27 +4858,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6018,9 +4881,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6029,27 +4891,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6072,21 +4924,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6108,10 +4955,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6120,24 +4965,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6150,30 +4986,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6181,10 +5007,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6193,24 +5017,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6223,51 +5038,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6277,28 +5077,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6309,11 +5103,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6321,23 +5113,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6349,39 +5134,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6389,23 +5164,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6417,41 +5185,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -6464,21 +5220,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6500,10 +5251,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6512,24 +5261,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6542,30 +5282,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6573,10 +5303,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6585,24 +5313,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6615,51 +5334,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6669,28 +5373,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6701,11 +5399,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6713,23 +5409,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6741,39 +5430,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6781,23 +5460,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6809,41 +5481,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -6852,48 +5512,44 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the specified - csi-node-driver DaemonSet containers. If omitted, - the csi-node-driver DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container by - name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named csi-node-driver DaemonSet - container's resources. If omitted, the csi-node-driver - DaemonSet will use its default value for this - container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -6910,9 +5566,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -6921,13 +5577,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -6937,66 +5591,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the csi-node-driver - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the csi-node-driver DaemonSet will use - its default value for nodeSelector. WARNING: Please - note that this field will modify the default csi-node-driver - DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use - its default value for tolerations. WARNING: Please - note that this field will override the default csi-node-driver - DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -7005,67 +5646,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are using - FIPS 140-2 validated cryptographic modules and standards. Default: - Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path for - FlexVolume. If not specified, FlexVolume will be enabled by default. - If set to 'None', FlexVolume will be disabled. The default is based - on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to be - specified. If specified then the specified value will be used as - the image path for each image. If not specified or empty, the default - for each image will be used. A special case value, UseDefault, is - supported to explicitly specify the default image path will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image to - be specified. If specified then the given value will be used as - a prefix on each image. If not specified or empty, no prefix will - be used. A special case value, UseDefault, is supported to explicitly - specify the default image prefix will be used for each image. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images to - be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled by default. - If set to ''None'', CSI will be disabled. Default: /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider of - the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to automatically - determine the current provider. If the specified value is not empty, - the Operator will still attempt auto-detection, but will additionally - compare the auto-detected value to the specified value to confirm - they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -7108,68 +5753,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node serves - prometheus metrics on. By default, metrics are not enabled. If specified, - this overrides any FelixConfiguration resources which may exist. - If omitted, then prometheus metrics may still be configured through - FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if type - = "RollingUpdate". --- TODO: Update this to follow our convention - for oneOf, whatever we decide it to be. Same as Deployment `strategy.rollingUpdate`. - See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute number - (ex: 5) or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute number is - calculated from percentage by rounding up to a minimum of - 1. Default value is 0. Example: when this is set to 30%, - at most 30% of the total number of nodes that should be - running the daemon pod (i.e. status.desiredNumberScheduled) - can have their a new pod created before the old pod is marked - as deleted. The update starts by launching new pods on 30% - of nodes. Once an updated pod is available (Ready for at - least minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable for - any reason (Ready transitions to false, is evicted, or is - drained) an updated pod is immediatedly created on that - node without considering surge limits. Allowing surge implies - the possibility that the resources consumed by the daemonset - on any given node can double if the readiness check fails, - and so resource intensive daemonsets should take into account - that they may cause evictions during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that can - be unavailable during the update. Value can be an absolute - number (ex: 5) or a percentage of total number of DaemonSet - pods at the start of the update (ex: 10%). Absolute number - is calculated from percentage by rounding up. This cannot - be 0 if MaxSurge is 0 Default value is 1. Example: when - this is set to 30%, at most 30% of the total number of nodes + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given time. - The update starts by stopping at most 30% of those DaemonSet - pods and then brings up new DaemonSet pods in their place. - Once the new pods are available, it then proceeds onto other - DaemonSet pods, thus ensuring that at least 70% of original - number of DaemonSet pods are available at all times during - the update.' + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -7182,14 +5827,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for component - Docker images. If specified then the given value must end with a - slash character (`/`) and all images will be pulled from this registry. - If not specified then the default registries will be used. A special - case value, UseDefault, is supported to explicitly specify the default - registries will be used. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -7198,24 +5843,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity characteristics - for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with the @@ -7225,30 +5869,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7261,30 +5901,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7306,60 +5942,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity requirements - specified by this field are not met at scheduling time, - the pod will NOT be scheduled onto the node. There is no - fallback to another affinity rules with this setting. This - may cause networking disruption or even catastrophic failure! - PreferredDuringSchedulingIgnoredDuringExecution should be - used for affinity unless there is a specific well understood - reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution is - set by default for AKS nodes, to avoid scheduling Typhas - on virtual-nodes. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7372,30 +6001,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7414,9 +6039,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. If used - in conjunction with the deprecated ComponentResources or TyphaAffinity, - then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -7425,30 +6050,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -7458,45 +6082,43 @@ spec: pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present only - if DeploymentStrategyType = RollingUpdate. to be. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be scheduled above the desired number of pods. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). This can not be 0 if - MaxUnavailable is 0. Absolute number is calculated - from percentage by rounding up. Defaults to 25%. - Example: when this is set to 30%, the new ReplicaSet - can be scaled up immediately when the rolling update - starts, such that the total number of old and new - pods do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be scaled - up further, ensuring that total number of pods running - at any time during the update is at most 130% of - desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of desired - pods (ex: 10%). Absolute number is calculated from - percentage by rounding down. This can not be 0 if - MaxSurge is 0. Defaults to 25%. Example: when this - is set to 30%, the old ReplicaSet can be scaled - down to 70% of desired pods immediately when the - rolling update starts. Once new pods are ready, - old ReplicaSet can be scaled down further, followed - by scaling up the new ReplicaSet, ensuring that - the total number of pods available at all times - during the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -7505,67 +6127,57 @@ spec: will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the typha pods. If specified, this overrides - any affinity that may be set on the typha Deployment. - If omitted, the typha Deployment will use its default - value for affinity. If used in conjunction with - the deprecated TyphaAffinity, then this value takes - precedence. WARNING: Please note that this field - will override the default calico-typha Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -7575,9 +6187,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7586,27 +6197,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7619,9 +6220,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7630,27 +6230,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7673,31 +6263,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7706,27 +6293,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7739,9 +6316,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7750,27 +6326,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7793,21 +6359,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -7829,10 +6390,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7841,24 +6400,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7871,30 +6421,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -7902,10 +6442,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7914,24 +6452,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7944,51 +6473,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -7998,28 +6512,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8030,11 +6538,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8042,23 +6548,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8070,39 +6569,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8110,23 +6599,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8138,41 +6620,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8185,21 +6655,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -8221,10 +6686,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8233,24 +6696,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8263,30 +6717,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -8294,10 +6738,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8306,24 +6748,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8336,51 +6769,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -8390,28 +6808,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8422,11 +6834,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8434,23 +6844,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8462,39 +6865,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8502,23 +6895,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8530,41 +6916,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8573,49 +6947,43 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha Deployment - will use its default values for its containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. Supported - values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment container's - resources. If omitted, the typha Deployment - will use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8632,9 +7000,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8643,13 +7011,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8657,50 +7023,43 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha init - containers. If specified, this overrides the specified - typha Deployment init containers. If omitted, the - typha Deployment will use its default values for - its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by name. - Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment init - container's resources. If omitted, the typha - Deployment will use its default value for - this init container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8717,9 +7076,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8728,13 +7087,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8744,97 +7101,81 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-typha Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-typha - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the pod - needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). If this - value is nil, the default grace period will be used - instead. The grace period is the duration in seconds - after the processes running in the pod are sent - a termination signal and the time when the processes - are forcibly halted with a kill signal. Set this - value longer than the expected cleanup time for - your process. Defaults to 30 seconds. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s tolerations. - If specified, this overrides any tolerations that - may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value - for tolerations. WARNING: Please note that this - field will override the default calico-typha Deployment - tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -8842,30 +7183,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8877,158 +7213,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -9046,8 +7348,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico or - TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -9056,15 +7359,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under [plugins] - [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -9087,18 +7394,19 @@ spec: installation. properties: calicoVersion: - description: CalicoVersion shows the current running version of calico. - CalicoVersion along with Variant is needed to know the exact version - deployed. + description: |- + CalicoVersion shows the current running version of calico. + CalicoVersion along with Variant is needed to know the exact + version deployed. type: string computed: description: Computed is the final installation including overlaid resources. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -9107,19 +7415,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -9127,13 +7434,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -9143,26 +7448,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -9170,43 +7474,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-kube-controllers - pods. If specified, this overrides any affinity - that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -9218,11 +7510,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9230,30 +7520,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9267,11 +7544,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9279,30 +7554,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9325,36 +7587,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9362,30 +7618,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9399,11 +7642,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9411,30 +7652,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9457,22 +7685,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -9495,12 +7717,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -9509,27 +7728,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9542,33 +7749,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9576,12 +7770,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -9590,27 +7781,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9623,55 +7802,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -9681,30 +7841,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -9717,10 +7869,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9729,24 +7879,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9759,30 +7900,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9790,10 +7921,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9802,24 +7931,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9832,44 +7952,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -9882,22 +7987,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -9920,12 +8019,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -9934,27 +8030,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9967,33 +8051,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -10001,12 +8072,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -10015,27 +8083,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10048,55 +8104,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -10106,30 +8143,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -10142,10 +8171,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10154,24 +8181,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10184,30 +8202,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -10215,10 +8223,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10227,24 +8233,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10257,44 +8254,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -10303,54 +8285,45 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the - specified calico-kube-controllers Deployment - containers. If omitted, the calico-kube-controllers - Deployment will use its default values for its - containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment - container by name. Supported values are: - calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -10366,9 +8339,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -10377,14 +8350,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -10394,76 +8364,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-kube-controllers Deployment nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the calico-kube-controllers Deployment - and each of this field''s key/value pairs are - added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already - exist in the object''s nodeSelector. If omitted, - the calico-kube-controllers Deployment will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the - default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -10483,39 +8433,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip - forwarding will be enabled for containers in the CNI configuration. - Default: Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the - Calico CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create - if none exist. At most one IP pool of each address family - may be specified. If omitted, a single pool will be configured - if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will - be used for. If not specified or empty, defaults - to ["Tunnel", "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the - main IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -10524,14 +8474,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: - IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -10544,15 +8495,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector - that will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -10560,61 +8513,63 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane - used for Linux nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, iptables mode is - used. Default: Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods - from running containers until their policy has been programmed - in the dataplane. The specified delay defines the maximum - amount of time that the Calico CNI plugin will wait for - policy to be programmed. \n Only applies to pods created - on Linux nodes. \n * A value of 0 disables pod startup delays. - \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to - use on the pod network. If not specified, Calico will perform - MTU auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -10628,30 +8583,31 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -10665,8 +8621,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -10688,21 +8645,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, it is disabled and - the operator will not render the Calico Windows nodes daemonset. - Default: Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -10711,19 +8667,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -10731,13 +8686,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -10747,68 +8700,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node pods. If - specified, this overrides any affinity that - may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use - its default value for affinity. WARNING: Please - note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -10820,11 +8761,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10832,30 +8771,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10869,11 +8795,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10881,30 +8805,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10927,36 +8838,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10964,30 +8869,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11001,11 +8893,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -11013,30 +8903,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11059,22 +8936,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -11097,12 +8968,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11111,27 +8979,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11144,33 +9000,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11178,12 +9021,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11192,27 +9032,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11225,55 +9053,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11283,30 +9092,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -11319,10 +9120,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11331,24 +9130,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11361,30 +9151,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11392,10 +9172,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11404,24 +9182,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11434,44 +9203,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11484,22 +9238,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -11522,12 +9270,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11536,27 +9281,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11569,33 +9302,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11603,12 +9323,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11617,27 +9334,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11650,55 +9355,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11708,30 +9394,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -11744,10 +9422,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11756,24 +9432,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11786,30 +9453,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11817,10 +9474,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11829,24 +9484,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11859,44 +9505,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11905,52 +9536,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node - containers. If specified, this overrides the - specified calico-node DaemonSet containers. - If omitted, the calico-node DaemonSet will use - its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by - name. Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -11966,9 +9589,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -11977,14 +9600,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -11992,21 +9612,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides - the specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use - its default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container - by name. Supported values are: install-cni, - hostpath-init, flexvol-driver, mount-bpffs, - node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -12016,35 +9633,28 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - init container's resources. If omitted, - the calico-node DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -12060,9 +9670,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -12071,14 +9681,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -12088,68 +9695,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node DaemonSet - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -12168,19 +9760,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -12188,13 +9779,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -12204,26 +9793,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -12231,42 +9819,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node-windows - pods. If specified, this overrides any affinity - that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the - default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -12278,11 +9855,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12290,30 +9865,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12327,11 +9889,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12339,30 +9899,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12385,36 +9932,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12422,30 +9963,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12459,11 +9987,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12471,30 +9997,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12517,22 +10030,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -12555,12 +10062,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12569,27 +10073,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12602,33 +10094,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12636,12 +10115,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12650,27 +10126,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12683,55 +10147,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -12741,30 +10186,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -12777,10 +10214,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12789,24 +10224,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12819,30 +10245,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12850,10 +10266,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12862,24 +10276,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12892,44 +10297,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -12942,22 +10332,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -12980,12 +10364,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12994,27 +10375,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13027,33 +10396,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13061,12 +10417,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -13075,27 +10428,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13108,55 +10449,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -13166,30 +10488,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -13202,10 +10516,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13214,24 +10526,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13244,30 +10547,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13275,10 +10568,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13287,24 +10578,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13317,44 +10599,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -13363,52 +10630,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the - specified calico-node-windows DaemonSet containers. - If omitted, the calico-node-windows DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet container's resources. If omitted, - the calico-node-windows DaemonSet will - use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -13424,9 +10683,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13435,14 +10694,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13450,23 +10706,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides - the specified calico-node-windows DaemonSet - init containers. If omitted, the calico-node-windows - DaemonSet will use its default values for its - init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init - container by name. Supported values are: - install-cni;hostpath-init, flexvol-driver, - mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -13476,35 +10727,28 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet init container's resources. - If omitted, the calico-node-windows DaemonSet - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -13520,9 +10764,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13531,14 +10775,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13548,68 +10789,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node-windows DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node-windows - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -13618,9 +10844,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is - deprecated and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -13629,19 +10855,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -13649,13 +10874,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -13665,26 +10888,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -13692,43 +10914,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-windows-upgrade - pods. If specified, this overrides any affinity - that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -13740,11 +10950,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13752,30 +10960,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13789,11 +10984,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13801,30 +10994,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13847,36 +11027,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13884,30 +11058,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13921,11 +11082,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13933,30 +11092,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13979,22 +11125,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -14017,12 +11157,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14031,27 +11168,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14064,33 +11189,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14098,12 +11210,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14112,27 +11221,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14145,55 +11242,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14203,30 +11281,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -14239,10 +11309,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14251,24 +11319,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14281,30 +11340,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14312,10 +11361,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14324,24 +11371,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14354,44 +11392,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14404,22 +11427,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -14442,12 +11459,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14456,27 +11470,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14489,33 +11491,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14523,12 +11512,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14537,27 +11523,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14570,55 +11544,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14628,30 +11583,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -14664,10 +11611,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14676,24 +11621,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14706,30 +11642,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14737,10 +11663,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14749,24 +11673,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14779,44 +11694,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14825,11 +11725,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the - specified calico-windows-upgrade DaemonSet containers. - If omitted, the calico-windows-upgrade DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -14842,33 +11741,27 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -14884,9 +11777,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -14895,14 +11788,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -14912,70 +11802,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-windows-upgrade DaemonSet nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-windows-upgrade DaemonSet - nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -14984,10 +11857,9 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a - CertificateSigningRequest to the certificates.k8s.io/v1beta1 - API in order to obtain TLS certificates. This feature requires - that you bring your own CSR signing and approval process, otherwise + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise pods will be stuck during initialization. properties: caCert: @@ -14996,9 +11868,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate - a key pair that is associated with the X.509 certificate - request. Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -15009,8 +11881,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature - of the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -15021,10 +11894,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to - accommodate for clusters with multiple signers. Must be - formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -15034,21 +11907,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management - that will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For - CNI Plugin Calico, this field defaults to Calico. * - For CNI Plugin GKE, this field defaults to HostLocal. + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. * For CNI Plugin AzureVNET, this field defaults to AzureVNET. * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only - if the CNI plugin is set to Calico, for all other values - of the CNI plugin the plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -15059,18 +11932,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in - the Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider - AKS, this field defaults to AzureVNET. * For KubernetesProvider - EKS, this field defaults to AmazonVPC. * If aws-node daemonset - exists in kube-system when the Installation resource is - created, this field defaults to AmazonVPC. * For all other - cases this field defaults to Calico. \n For the value Calico, - the CNI plugin binaries and CNI config will be installed - as part of deployment, for all other values the CNI plugin - binaries and CNI config is a dependency that is expected - to be installed separately. \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -15081,15 +11953,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used - to customize the resource requirements for each component. Node, - Typha, and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config - fields in Installation.Spec instead. The ComponentResource - struct associates a ResourceRequirements with a component - by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the @@ -15105,19 +11976,20 @@ spec: and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. \n This field - is immutable. It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where - this field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -15134,8 +12006,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -15144,11 +12017,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -15159,56 +12032,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control - plane nodes on which to run Calico components. This is globally - applied to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of - the control plane core components will be deployed. This field - applies to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which - are then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -15223,19 +12094,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15243,13 +12113,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -15259,26 +12127,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15286,42 +12153,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the csi-node-driver pods. - If specified, this overrides any affinity that - may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will - use its default value for affinity. WARNING: - Please note that this field will override the - default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -15333,11 +12189,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15345,30 +12199,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15382,11 +12223,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15394,30 +12233,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15440,36 +12266,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15477,30 +12297,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15514,11 +12321,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15526,30 +12331,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15572,22 +12364,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -15610,12 +12396,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15624,27 +12407,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15657,33 +12428,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15691,12 +12449,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15705,27 +12460,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15738,55 +12481,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -15796,30 +12520,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -15832,10 +12548,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15844,24 +12558,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15874,30 +12579,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15905,10 +12600,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15917,24 +12610,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15947,44 +12631,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -15997,22 +12666,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -16035,12 +12698,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16049,27 +12709,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16082,33 +12730,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16116,12 +12751,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16130,27 +12762,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16163,55 +12783,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -16221,30 +12822,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -16257,10 +12850,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16269,24 +12860,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16299,30 +12881,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16330,10 +12902,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16342,24 +12912,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16372,44 +12933,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -16418,50 +12964,45 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the - specified csi-node-driver DaemonSet containers. - If omitted, the csi-node-driver DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container - by name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named csi-node-driver - DaemonSet container's resources. If omitted, - the csi-node-driver DaemonSet will use - its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -16477,9 +13018,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -16488,14 +13029,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -16505,68 +13043,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - csi-node-driver DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the csi-node-driver - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default csi-node-driver DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -16575,68 +13098,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are - using FIPS 140-2 validated cryptographic modules and standards. - Default: Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path - for FlexVolume. If not specified, FlexVolume will be enabled - by default. If set to 'None', FlexVolume will be disabled. The - default is based on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to - be specified. If specified then the specified value will be - used as the image path for each image. If not specified or empty, - the default for each image will be used. A special case value, - UseDefault, is supported to explicitly specify the default image - path will be used for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image - to be specified. If specified then the given value will be used - as a prefix on each image. If not specified or empty, no prefix - will be used. A special case value, UseDefault, is supported - to explicitly specify the default image prefix will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images - to be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information - to let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled - by default. If set to ''None'', CSI will be disabled. Default: - /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider - of the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to - automatically determine the current provider. If the specified - value is not empty, the Operator will still attempt auto-detection, - but will additionally compare the auto-detected value to the - specified value to confirm they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -16680,71 +13206,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node - serves prometheus metrics on. By default, metrics are not enabled. - If specified, this overrides any FelixConfiguration resources - which may exist. If omitted, then prometheus metrics may still - be configured through FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if - type = "RollingUpdate". --- TODO: Update this to follow - our convention for oneOf, whatever we decide it to be. Same - as Deployment `strategy.rollingUpdate`. See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute - number (ex: 5) or a percentage of desired pods (ex: - 10%). This can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding up - to a minimum of 1. Default value is 0. Example: when - this is set to 30%, at most 30% of the total number - of nodes that should be running the daemon pod (i.e. - status.desiredNumberScheduled) can have their a new - pod created before the old pod is marked as deleted. - The update starts by launching new pods on 30% of nodes. - Once an updated pod is available (Ready for at least - minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable - for any reason (Ready transitions to false, is evicted, - or is drained) an updated pod is immediatedly created - on that node without considering surge limits. Allowing - surge implies the possibility that the resources consumed - by the daemonset on any given node can double if the - readiness check fails, and so resource intensive daemonsets - should take into account that they may cause evictions - during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that - can be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of total number - of DaemonSet pods at the start of the update (ex: 10%). - Absolute number is calculated from percentage by rounding - up. This cannot be 0 if MaxSurge is 0 Default value - is 1. Example: when this is set to 30%, at most 30% - of the total number of nodes that should be running - the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given - time. The update starts by stopping at most 30% of those - DaemonSet pods and then brings up new DaemonSet pods - in their place. Once the new pods are available, it - then proceeds onto other DaemonSet pods, thus ensuring - that at least 70% of original number of DaemonSet pods - are available at all times during the update.' + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -16757,15 +13280,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for - component Docker images. If specified then the given value must - end with a slash character (`/`) and all images will be pulled - from this registry. If not specified then the default registries - will be used. A special case value, UseDefault, is supported - to explicitly specify the default registries will be used. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -16774,24 +13296,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity - characteristics for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -16801,32 +13322,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16839,32 +13354,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16886,63 +13395,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity - requirements specified by this field are not met at - scheduling time, the pod will NOT be scheduled onto - the node. There is no fallback to another affinity rules - with this setting. This may cause networking disruption - or even catastrophic failure! PreferredDuringSchedulingIgnoredDuringExecution - should be used for affinity unless there is a specific - well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution - is set by default for AKS nodes, to avoid scheduling - Typhas on virtual-nodes. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16955,32 +13454,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16999,9 +13492,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. - If used in conjunction with the deprecated ComponentResources - or TyphaAffinity, then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -17010,32 +13503,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the typha - Deployment. If omitted, the typha Deployment will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -17045,48 +13535,43 @@ spec: existing pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present - only if DeploymentStrategyType = RollingUpdate. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be scheduled above the desired number of - pods. Value can be an absolute number (ex: 5) - or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding - up. Defaults to 25%. Example: when this is set - to 30%, the new ReplicaSet can be scaled up - immediately when the rolling update starts, - such that the total number of old and new pods - do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be - scaled up further, ensuring that total number - of pods running at any time during the update - is at most 130% of desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be unavailable during the update. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). Absolute number is - calculated from percentage by rounding down. - This can not be 0 if MaxSurge is 0. Defaults - to 25%. Example: when this is set to 30%, the - old ReplicaSet can be scaled down to 70% of - desired pods immediately when the rolling update - starts. Once new pods are ready, old ReplicaSet - can be scaled down further, followed by scaling - up the new ReplicaSet, ensuring that the total - number of pods available at all times during - the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -17095,69 +13580,57 @@ spec: that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the typha pods. If specified, - this overrides any affinity that may be set - on the typha Deployment. If omitted, the typha - Deployment will use its default value for affinity. - If used in conjunction with the deprecated TyphaAffinity, - then this value takes precedence. WARNING: Please - note that this field will override the default - calico-typha Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -17169,11 +13642,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17181,30 +13652,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17218,11 +13676,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17230,30 +13686,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17276,36 +13719,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17313,30 +13750,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17350,11 +13774,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17362,30 +13784,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17408,22 +13817,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17446,12 +13849,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17460,27 +13860,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17493,33 +13881,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17527,12 +13902,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17541,27 +13913,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17574,55 +13934,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -17632,30 +13973,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -17668,10 +14001,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17680,24 +14011,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17710,30 +14032,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17741,10 +14053,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17753,24 +14063,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17783,44 +14084,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -17833,22 +14119,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17871,12 +14151,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17885,27 +14162,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17918,33 +14183,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17952,12 +14204,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17966,27 +14215,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17999,55 +14236,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -18057,30 +14275,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -18093,10 +14303,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18105,24 +14313,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18135,30 +14334,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -18166,10 +14355,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18178,24 +14365,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18208,44 +14386,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -18254,52 +14417,44 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha - Deployment will use its default values for its - containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. - Supported values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - container's resources. If omitted, the - typha Deployment will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18315,9 +14470,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18326,14 +14481,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18341,52 +14493,44 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha - init containers. If specified, this overrides - the specified typha Deployment init containers. - If omitted, the typha Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by - name. Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - init container's resources. If omitted, - the typha Deployment will use its default - value for this init container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18402,9 +14546,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18413,14 +14557,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18430,114 +14571,92 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-typha Deployment nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-typha Deployment - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the - pod needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative - integer. The value zero indicates stop immediately - via the kill signal (no opportunity to shut - down). If this value is nil, the default grace - period will be used instead. The grace period - is the duration in seconds after the processes - running in the pod are sent a termination signal - and the time when the processes are forcibly - halted with a kill signal. Set this value longer - than the expected cleanup time for your process. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the typha Deployment. - If omitted, the typha Deployment will use its - default value for tolerations. WARNING: Please - note that this field will override the default - calico-typha Deployment tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes - how a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way - which abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find - matching pods. Pods that match this label - selector are counted to determine the - number of pods in their corresponding - topology domain. + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -18545,20 +14664,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -18570,174 +14685,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of - pod label keys to select the pods over - which spreading will be calculated. The - keys are used to lookup values from the - incoming pod labels, those key-value labels - are ANDed with labelSelector to select - the group of existing pods over which - spreading will be calculated for the incoming - pod. The same key is forbidden to exist - in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the - incoming pod labels will be ignored. A - null or empty list means only match against - labelSelector. \n This is a beta field - and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by - default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree - to which pods may be unevenly distributed. - When `whenUnsatisfiable=DoNotSchedule`, - it is the maximum permitted difference - between the number of matching pods in - the target topology and the global minimum. - The global minimum is the minimum number - of matching pods in an eligible domain - or zero if the number of eligible domains - is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 2/2/1: In this case, the global - minimum is 1. | zone1 | zone2 | zone3 - | | P P | P P | P | - if MaxSkew - is 1, incoming pod can only be scheduled - to zone3 to become 2/2/2; scheduling it - onto zone1(zone2) would make the ActualSkew(3-1) - on zone1(zone2) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled - onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to - topologies that satisfy it. It''s a required - field. Default value is 1 and 0 is not - allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, - and then the calculation of Skew is performed. - And when the number of eligible domains - with matching topology keys equals or - greater than minDomains, this value has - no effect on scheduling. As a result, - when the number of eligible domains is - less than minDomains, scheduler won't - schedule more than maxSkew Pods to those - domains. If value is nil, the constraint - behaves as if MinDomains is equal to 1. - Valid values are integers greater than - 0. When value is not nil, WhenUnsatisfiable - must be DoNotSchedule. \n For example, - in a 3-zone cluster, MaxSkew is set to - 2, MinDomains is set to 5 and pods with - the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P - P | P P | The number of domains is - less than 5(MinDomains), so \"global minimum\" - is treated as 0. In this situation, new - pod with the same labelSelector cannot - be scheduled, because computed skew will - be 3(3 - 0) if new Pod is scheduled to - any of the three zones, it will violate - MaxSkew. \n This is a beta field and requires - the MinDomainsInPodTopologySpread feature - gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates - how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included - in the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in - the calculations. \n If this value is - nil, the behavior is equivalent to the - Honor policy. This is a beta-level feature - default enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates - how we will treat node taints when calculating + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - - Honor: nodes without taints, along with - tainted nodes for which the incoming pod - has a toleration, are included. - Ignore: - node taints are ignored. All nodes are - included. \n If this value is nil, the - behavior is equivalent to the Ignore policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered - to be in the same topology. We consider - each as a "bucket", and try - to put balanced number of pods into each - bucket. We define a domain as a particular - instance of a topology. Also, we define - an eligible domain as a domain whose nodes - meet the requirements of nodeAffinityPolicy - and nodeTaintsPolicy. e.g. If TopologyKey - is "kubernetes.io/hostname", each Node - is a domain of that topology. And, if - TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates - how to deal with a pod if it doesn''t - satisfy the spread constraint. - DoNotSchedule - (default) tells the scheduler not to schedule - it. - ScheduleAnyway tells the scheduler - to schedule the pod in any location, but - giving higher precedence to topologies - that would help reduce the skew. A constraint - is considered "Unsatisfiable" for an incoming - pod if and only if every possible node - assignment for that pod would violate - "MaxSkew" on some topology. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 - | | P P P | P | P | If WhenUnsatisfiable - is set to DoNotSchedule, incoming pod - can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). - In other words, the cluster can still - be imbalanced, but scheduler won''t make - it *more* imbalanced. It''s a required - field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -18755,8 +14820,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico - or TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -18765,15 +14831,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under - [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -18792,47 +14862,47 @@ spec: type: object type: object conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -18846,11 +14916,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -18863,14 +14934,14 @@ spec: type: object type: array imageSet: - description: ImageSet is the name of the ImageSet being used, if there - is an ImageSet that is being used. If an ImageSet is not being used - then this will not be set. + description: |- + ImageSet is the name of the ImageSet being used, if there is an ImageSet + that is being used. If an ImageSet is not being used then this will not be set. type: string mtu: - description: MTU is the most recently observed value for pod network - MTU. This may be an explicitly configured value, or based on Calico's - native auto-detetion. + description: |- + MTU is the most recently observed value for pod network MTU. This may be an explicitly + configured value, or based on Calico's native auto-detetion. format: int32 type: integer variant: diff --git a/charts/tigera-operator/crds/operator.tigera.io_tigerastatuses_crd.yaml b/charts/tigera-operator/crds/operator.tigera.io_tigerastatuses_crd.yaml index b1087f8a291..f6affee8042 100644 --- a/charts/tigera-operator/crds/operator.tigera.io_tigerastatuses_crd.yaml +++ b/charts/tigera-operator/crds/operator.tigera.io_tigerastatuses_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: tigerastatuses.operator.tigera.io spec: group: operator.tigera.io @@ -37,14 +37,19 @@ spec: Calico or a Calico Enterprise functional area. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -55,9 +60,9 @@ spec: description: TigeraStatusStatus defines the observed state of TigeraStatus properties: conditions: - description: Conditions represents the latest observed set of conditions - for this component. A component may be one or more of Available, - Progressing, or Degraded. + description: |- + Conditions represents the latest observed set of conditions for this component. A component may be one or more of + Available, Progressing, or Degraded. items: description: TigeraStatusCondition represents a condition attached to a particular component. @@ -72,11 +77,10 @@ spec: context. type: string observedGeneration: - description: observedGeneration represents the generation that - the condition was set based upon. For instance, if generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the generation that the condition was set based upon. + For instance, if generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 type: integer reason: diff --git a/charts/tigera-operator/templates/tigera-operator/01-kubernetes-services-endpoint.yaml b/charts/tigera-operator/templates/tigera-operator/01-kubernetes-services-endpoint.yaml index b99441deb64..5f154b2c616 100644 --- a/charts/tigera-operator/templates/tigera-operator/01-kubernetes-services-endpoint.yaml +++ b/charts/tigera-operator/templates/tigera-operator/01-kubernetes-services-endpoint.yaml @@ -5,6 +5,6 @@ metadata: name: kubernetes-services-endpoint namespace: {{.Release.Namespace}} data: - KUBERNETES_SERVICE_HOST: {{ .Values.kubernetesServiceEndpoint.host }} + KUBERNETES_SERVICE_HOST: {{ .Values.kubernetesServiceEndpoint.host | quote }} KUBERNETES_SERVICE_PORT: {{ .Values.kubernetesServiceEndpoint.port | quote }} {{- end }} diff --git a/charts/tigera-operator/templates/tigera-operator/02-role-tigera-operator.yaml b/charts/tigera-operator/templates/tigera-operator/02-role-tigera-operator.yaml index 3f8401c34cb..ba622c9ef1d 100644 --- a/charts/tigera-operator/templates/tigera-operator/02-role-tigera-operator.yaml +++ b/charts/tigera-operator/templates/tigera-operator/02-role-tigera-operator.yaml @@ -214,6 +214,12 @@ rules: - watch - create - update + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - delete # Needed for operator lock - apiGroups: - coordination.k8s.io @@ -351,3 +357,38 @@ rules: - update - delete {{- end }} + # For tiered network policy actions, tigera-apiserver requires that we authorize the operator for the tier.networkpolicies and tier.globalnetworkpolicies pseudo-kinds. + - apiGroups: + - projectcalico.org + resourceNames: + - allow-tigera.* + resources: + - tier.networkpolicies + - tier.globalnetworkpolicies + verbs: + - list + - watch + - get + - create + - update + - delete + # For tiered network policy actions, tigera-apiserver requires get authorization on the associated tier. + - apiGroups: + - projectcalico.org + resourceNames: + - allow-tigera + resources: + - tiers + verbs: + - get + - delete + - update + # Separated from the above rule since resourceNames does not support the create verb, and requires a field selector for list/watch verbs. + - apiGroups: + - projectcalico.org + resources: + - tiers + verbs: + - create + - list + - watch diff --git a/cni-plugin/.semaphore/cleanup.yml b/cni-plugin/.semaphore/cleanup.yml index 59c85ed307f..381b6f83c2c 100644 --- a/cni-plugin/.semaphore/cleanup.yml +++ b/cni-plugin/.semaphore/cleanup.yml @@ -2,7 +2,7 @@ version: v1.0 name: CNIPlugin agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: @@ -35,7 +35,7 @@ blocks: - name: Clean up winfv aws resources commands: - aws ec2 delete-key-pair --key-name ${KEYPAIR_NAME} || true - - cd ~/calico/process/testing/winfv && NAME_PREFIX="${CLUSTER_NAME}-containerd" ./setup-fv.sh -q -u || true + - cd ~/calico/process/testing/winfv-cni-plugin && NAME_PREFIX="${CLUSTER_NAME}-containerd" ./setup-fv.sh -q -u || true - NAME_PREFIX="${CLUSTER_NAME}-docker" ./setup-fv.sh -q -u | true env_vars: - name: AWS_DEFAULT_REGION diff --git a/cni-plugin/.semaphore/semaphore.yml b/cni-plugin/.semaphore/semaphore.yml index 47723a3312b..a371ebb8ee7 100644 --- a/cni-plugin/.semaphore/semaphore.yml +++ b/cni-plugin/.semaphore/semaphore.yml @@ -6,7 +6,7 @@ execution_time_limit: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 auto_cancel: @@ -107,7 +107,7 @@ blocks: - artifact push job ${REPORT_DIR} --destination semaphore/test-results --expire-in ${SEMAPHORE_ARTIFACT_EXPIRY} || true - artifact push job ${LOGS_DIR} --destination semaphore/logs --expire-in ${SEMAPHORE_ARTIFACT_EXPIRY} || true - aws ec2 delete-key-pair --key-name ${KEYPAIR_NAME} || true - - cd ~/calico/process/testing/winfv && NAME_PREFIX="${CLUSTER_NAME}" ./setup-fv.sh -q -u + - cd ~/calico/process/testing/winfv-cni-plugin && NAME_PREFIX="${CLUSTER_NAME}" ./setup-fv.sh -q -u env_vars: - name: SEMAPHORE_ARTIFACT_EXPIRY value: 2w @@ -152,7 +152,7 @@ blocks: - artifact push job ${REPORT_DIR} --destination semaphore/test-results --expire-in ${SEMAPHORE_ARTIFACT_EXPIRY} || true - artifact push job ${LOGS_DIR} --destination semaphore/logs --expire-in ${SEMAPHORE_ARTIFACT_EXPIRY} || true - aws ec2 delete-key-pair --key-name ${KEYPAIR_NAME} || true - - cd ~/calico/process/testing/winfv && NAME_PREFIX="${CLUSTER_NAME}" ./setup-fv.sh -q -u + - cd ~/calico/process/testing/winfv-cni-plugin && NAME_PREFIX="${CLUSTER_NAME}" ./setup-fv.sh -q -u env_vars: - name: SEMAPHORE_ARTIFACT_EXPIRY value: 2w diff --git a/cni-plugin/.semaphore/update_pins.yml b/cni-plugin/.semaphore/update_pins.yml index 7304863ff5e..69ef14ee02a 100644 --- a/cni-plugin/.semaphore/update_pins.yml +++ b/cni-plugin/.semaphore/update_pins.yml @@ -6,7 +6,7 @@ execution_time_limit: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 global_job_config: diff --git a/cni-plugin/Makefile b/cni-plugin/Makefile index f5e1784ea33..56bdb08184d 100644 --- a/cni-plugin/Makefile +++ b/cni-plugin/Makefile @@ -280,7 +280,6 @@ release-build: .release-$(VERSION).created $(MAKE) retag-build-images-with-registries RELEASE=true IMAGETAG=latest $(MAKE) FIPS=true retag-build-images-with-registries RELEASE=true IMAGETAG=$(VERSION)-fips LATEST_IMAGE_TAG=latest-fips $(MAKE) FIPS=true retag-build-images-with-registries RELEASE=true IMAGETAG=latest-fips LATEST_IMAGE_TAG=latest-fips - $(MAKE) release-verify touch $@ ## Verifies the release artifacts produces by `make release-build` are correct. @@ -305,7 +304,7 @@ release-verify-fips: go tool nm .tmp/calico | grep '_Cfunc__goboringcrypto_' 1> /dev/null || echo "ERROR: Binary in image '$(IMAGE)' is missing expected goboring symbols" rm -rf .tmp -release-publish: release-prereqs .release-$(VERSION).published +release-publish: release-prereqs release-verify .release-$(VERSION).published .release-$(VERSION).published: $(MAKE) push-images-to-registries push-manifests IMAGETAG=$(VERSION) RELEASE=$(RELEASE) CONFIRM=$(CONFIRM) $(MAKE) FIPS=true push-images-to-registries push-manifests IMAGETAG=$(VERSION)-fips RELEASE=$(RELEASE) CONFIRM=$(CONFIRM) @@ -317,7 +316,7 @@ release-publish: release-prereqs .release-$(VERSION).published # WARNING: Only run this target if this release is the latest stable release. Do NOT # run this target for alpha / beta / release candidate builds, or patches to earlier Calico versions. ## Pushes `latest` release images. WARNING: Only run this for latest stable releases. -release-publish-latest: release-prereqs +release-publish-latest: release-prereqs release-verify # Check latest versions match. if ! docker run $(CNI_PLUGIN_IMAGE):latest-$(ARCH) calico -v | grep '^$(VERSION)$$'; then echo "Reported version:" `docker run $(CNI_PLUGIN_IMAGE):latest-$(ARCH) calico -v` "\nExpected version: $(VERSION)"; false; else echo "\nVersion check passed\n"; fi if ! docker run quay.io/$(CNI_PLUGIN_IMAGE):latest-$(ARCH) calico -v | grep '^$(VERSION)$$'; then echo "Reported version:" `docker run quay.io/$(CNI_PLUGIN_IMAGE):latest-$(ARCH) calico -v` "\nExpected version: $(VERSION)"; false; else echo "\nVersion check passed\n"; fi diff --git a/cni-plugin/internal/pkg/azure/network.go b/cni-plugin/internal/pkg/azure/network.go index 61c90b18f43..d748355ea7c 100644 --- a/cni-plugin/internal/pkg/azure/network.go +++ b/cni-plugin/internal/pkg/azure/network.go @@ -17,7 +17,6 @@ package azure import ( "bytes" "encoding/json" - "fmt" "os" "github.com/natefinch/atomic" @@ -63,7 +62,7 @@ func (an *AzureNetwork) Load() error { } func (an *AzureNetwork) filename() string { - return fmt.Sprintf(networksDir + an.Name + "/network.json") + return networksDir + an.Name + "/network.json" } func (an *AzureNetwork) ensureDir() error { diff --git a/cni-plugin/internal/pkg/testutils/utils_linux.go b/cni-plugin/internal/pkg/testutils/utils_linux.go index ef3121b731c..b774743c39f 100644 --- a/cni-plugin/internal/pkg/testutils/utils_linux.go +++ b/cni-plugin/internal/pkg/testutils/utils_linux.go @@ -39,6 +39,7 @@ import ( k8sconversion "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/names" + "github.com/projectcalico/calico/libcalico-go/lib/netlinkutils" "github.com/google/uuid" log "github.com/sirupsen/logrus" @@ -282,16 +283,21 @@ func RunCNIPluginWithId( } err = targetNs.Do(func(_ ns.NetNS) error { - contVeth, err = netlink.LinkByName(ifName) + nlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) if err != nil { return err } - contAddr, err = netlink.AddrList(contVeth, syscall.AF_INET) + contVeth, err = nlHandle.LinkByName(ifName) if err != nil { return err } - v6Addrs, err := netlink.AddrList(contVeth, syscall.AF_INET6) + + contAddr, err = netlinkutils.AddrListRetryEINTR(nlHandle, contVeth, syscall.AF_INET) + if err != nil { + return err + } + v6Addrs, err := netlinkutils.AddrListRetryEINTR(nlHandle, contVeth, syscall.AF_INET6) if err != nil { return err } @@ -302,7 +308,7 @@ func RunCNIPluginWithId( } } - contRoutes, err = netlink.RouteList(contVeth, syscall.AF_INET) + contRoutes, err = netlinkutils.RouteListRetryEINTR(nlHandle, contVeth, syscall.AF_INET) if err != nil { return err } diff --git a/cni-plugin/pkg/dataplane/grpc/grpc_dataplane.go b/cni-plugin/pkg/dataplane/grpc/grpc_dataplane.go index f1d603dc821..e30e33a5f2b 100644 --- a/cni-plugin/pkg/dataplane/grpc/grpc_dataplane.go +++ b/cni-plugin/pkg/dataplane/grpc/grpc_dataplane.go @@ -1,5 +1,5 @@ // Copyright 2020 Cisco Systems Inc -// Copyright (c) 2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import ( "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/resolver" "github.com/projectcalico/calico/cni-plugin/pkg/dataplane/grpc/proto" "github.com/projectcalico/calico/cni-plugin/pkg/types" @@ -45,6 +46,10 @@ type grpcDataplane struct { options map[string]string } +func init() { + resolver.SetDefaultScheme("passthrough") +} + func NewGrpcDataplane(conf types.NetConf, logger *logrus.Entry) (*grpcDataplane, error) { socket, ok := conf.DataplaneOptions["socket"].(string) if !ok { @@ -79,7 +84,7 @@ func (d *grpcDataplane) DoNetworking( annotations map[string]string, ) (ifName, contTapMAC string, err error) { d.logger.Infof("Connecting to GRPC backend server at %s", d.socket) - conn, err := grpc.Dial(d.socket, grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.NewClient(d.socket, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return "", "", fmt.Errorf("cannot connect to grpc dataplane: %v", err) } @@ -142,7 +147,7 @@ func (d *grpcDataplane) DoNetworking( func (d *grpcDataplane) CleanUpNamespace(args *skel.CmdArgs) error { d.logger.Infof("Connecting to GRPC backend server at %s", d.socket) - conn, err := grpc.Dial(d.socket, grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.NewClient(d.socket, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return fmt.Errorf("cannot connect to grpc dataplane: %v", err) } diff --git a/cni-plugin/pkg/dataplane/linux/dataplane_linux.go b/cni-plugin/pkg/dataplane/linux/dataplane_linux.go index b416d81d508..7f51613a8f9 100644 --- a/cni-plugin/pkg/dataplane/linux/dataplane_linux.go +++ b/cni-plugin/pkg/dataplane/linux/dataplane_linux.go @@ -33,6 +33,7 @@ import ( "github.com/projectcalico/calico/cni-plugin/pkg/types" api "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" calicoclient "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/netlinkutils" ) type linuxDataplane struct { @@ -51,6 +52,9 @@ func NewLinuxDataplane(conf types.NetConf, logger *logrus.Entry) *linuxDataplane } } +// DoNetworking sets up the network for the container's netns. It creates the +// veth pair with one end in the host network namespace and the other in the +// container's network namespace. It also sets up addresses and routes. func (d *linuxDataplane) DoNetworking( ctx context.Context, calicoClient calicoclient.Interface, @@ -62,27 +66,63 @@ func (d *linuxDataplane) DoNetworking( annotations map[string]string, ) (hostVethName, contVethMAC string, err error) { hostVethName = desiredVethName - contVethName := args.IfName - var hasIPv4, hasIPv6 bool - d.logger.Infof("Setting the host side veth name to %s", hostVethName) hostNlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) if err != nil { return "", "", fmt.Errorf("failed to create host netlink handle: %v", err) } - defer hostNlHandle.Close() + contVethMAC, err = d.DoWorkloadNetnsSetUp( + hostNlHandle, + args.Netns, + result.IPs, // Note: DoWorkloadNetnsSetUp updates CIDR masks. + args.IfName, + hostVethName, + routes, + annotations, + ) + if err != nil { + return "", "", err + } + + hostVeth, err := hostNlHandle.LinkByName(hostVethName) + if err != nil { + return "", "", fmt.Errorf("failed to lookup %q: %v", hostVethName, err) + } + + // Add the routes to host veth in the host namespace. + err = SetupRoutes(hostNlHandle, hostVeth, result) + if err != nil { + return "", "", fmt.Errorf("error adding host side routes for interface: %s, error: %s", hostVeth.Attrs().Name, err) + } + + return hostVethName, contVethMAC, err +} + +// DoWorkloadNetnsSetUp only sets up the veth and the in-netns routes. +// +// Note: this method is also used by the Felix FV test-workload to create +// a simulated workload. +func (d *linuxDataplane) DoWorkloadNetnsSetUp( + hostNlHandle *netlink.Handle, + netnsPath string, + ipAddrs []*cniv1.IPConfig, + contVethName string, + hostVethName string, + routes []*net.IPNet, + annotations map[string]string, +) (contVethMAC string, err error) { // Clean up if hostVeth exists. if oldHostVeth, err := hostNlHandle.LinkByName(hostVethName); err == nil { if err = hostNlHandle.LinkDel(oldHostVeth); err != nil { - return "", "", fmt.Errorf("failed to delete old hostVeth %v: %v", hostVethName, err) + return "", fmt.Errorf("failed to delete old hostVeth %v: %v", hostVethName, err) } d.logger.Infof("Cleaning old hostVeth: %v", hostVethName) } - err = ns.WithNetNSPath(args.Netns, func(hostNS ns.NetNS) error { + err = ns.WithNetNSPath(netnsPath, func(hostNS ns.NetNS) error { la := netlink.NewLinkAttrs() la.Name = contVethName la.MTU = d.mtu @@ -116,7 +156,8 @@ func (d *linuxDataplane) DoNetworking( } // Figure out whether we have IPv4 and/or IPv6 addresses. - for _, addr := range result.IPs { + var hasIPv4, hasIPv6 bool + for _, addr := range ipAddrs { if addr.Address.IP.To4() != nil { hasIPv4 = true addr.Address.Mask = net.CIDRMask(32, 32) @@ -284,7 +325,7 @@ func (d *linuxDataplane) DoNetworking( } // Now add the IPs to the container side of the veth. - for _, addr := range result.IPs { + for _, addr := range ipAddrs { if err = netlink.AddrAdd(contVeth, &netlink.Addr{IPNet: &addr.Address}); err != nil { return fmt.Errorf("failed to add IP addr to %q: %v", contVeth, err) } @@ -299,21 +340,10 @@ func (d *linuxDataplane) DoNetworking( if err != nil { d.logger.Errorf("Error creating veth: %s", err) - return "", "", err - } - - hostVeth, err := hostNlHandle.LinkByName(hostVethName) - if err != nil { - return "", "", fmt.Errorf("failed to lookup %q: %v", hostVethName, err) + return "", err } - // Add the routes to host veth in the host namespace. - err = SetupRoutes(hostNlHandle, hostVeth, result) - if err != nil { - return "", "", fmt.Errorf("error adding host side routes for interface: %s, error: %s", hostVeth.Attrs().Name, err) - } - - return hostVethName, contVethMAC, err + return } func disableDAD(contVethName string) error { @@ -343,9 +373,9 @@ func SetupRoutes(hostNlHandle *netlink.Handle, hostVeth netlink.Link, result *cn // Route already exists, but not necessarily pointing to the same interface. case syscall.EEXIST: // List all the routes for the interface. - routes, err := hostNlHandle.RouteList(hostVeth, netlink.FAMILY_ALL) + routes, err := netlinkutils.RouteListRetryEINTR(hostNlHandle, hostVeth, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("error listing routes") + return fmt.Errorf("error listing routes: %v", err) } // Go through all the routes pointing to the interface, and see if any of them is @@ -363,9 +393,9 @@ func SetupRoutes(hostNlHandle *netlink.Handle, hostVeth netlink.Link, result *cn } // Search all routes and report the conflict, search the name of the iface - routes, err = hostNlHandle.RouteList(nil, netlink.FAMILY_ALL) + routes, err = netlinkutils.RouteListRetryEINTR(hostNlHandle, nil, netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("error listing routes") + return fmt.Errorf("error listing routes: %v", err) } var conflict string diff --git a/cni-plugin/pkg/dataplane/windows/dataplane_windows.go b/cni-plugin/pkg/dataplane/windows/dataplane_windows.go index c161621338b..81bfc17327d 100644 --- a/cni-plugin/pkg/dataplane/windows/dataplane_windows.go +++ b/cni-plugin/pkg/dataplane/windows/dataplane_windows.go @@ -32,10 +32,8 @@ import ( "github.com/juju/clock" "github.com/juju/errors" "github.com/juju/mutex" - "github.com/rakelkar/gonetsh/netsh" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/util/wait" - utilexec "k8s.io/utils/exec" "github.com/projectcalico/calico/cni-plugin/internal/pkg/utils/cri" "github.com/projectcalico/calico/cni-plugin/internal/pkg/utils/winpol" @@ -43,6 +41,7 @@ import ( api "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" calicoclient "github.com/projectcalico/calico/libcalico-go/lib/clientv3" "github.com/projectcalico/calico/libcalico-go/lib/options" + "github.com/projectcalico/calico/libcalico-go/lib/winutils" ) const ( @@ -373,10 +372,10 @@ func ensureVxlanNetworkExists(networkName string, subNet *net.IPNet, vni uint64, } // Wait for the interface with the management IP - netshHelper := netsh.New(utilexec.New()) logger.Infof("Waiting to get net interface for HNSNetwork %s (%s)", networkName, newNetwork.ManagementIP) waitErr = wait.Poll(500*time.Millisecond, 5*time.Second, func() (done bool, err error) { - _, lastErr = netshHelper.GetInterfaceByIP(newNetwork.ManagementIP) + mgmtIP := net.ParseIP(newNetwork.ManagementIP) + _, lastErr = lookupManagementIface(mgmtIP, logger) return lastErr == nil, nil }) if waitErr == wait.ErrWaitTimeout { @@ -609,8 +608,6 @@ func CreateAndAttachHostEP(epName string, hnsNetwork *hcsshim.HNSNetwork, subNet } func chkMgmtIPandEnableForwarding(networkName string, hnsEndpoint *hcsshim.HNSEndpoint, logger *logrus.Entry) (network *hcsshim.HNSNetwork, err error) { - netHelper := netsh.New(nil) - startTime := time.Now() logCxt := logger.WithField("network", networkName) @@ -635,13 +632,14 @@ func chkMgmtIPandEnableForwarding(networkName string, hnsEndpoint *hcsshim.HNSEn continue } - if mgmtIface, err := netHelper.GetInterfaceByIP(network.ManagementIP); err != nil { + mgmtIP := net.ParseIP(network.ManagementIP) + if mgmtIface, err := lookupManagementIface(mgmtIP, logger); err != nil { logCxt.WithField("ip", network.ManagementIP).WithError(err).Warn( "Waiting for interface matching management IP...") time.Sleep(1 * time.Second) continue } else { - err := enableForwarding(netHelper, mgmtIface, logger) + err := enableForwarding(mgmtIface, logger) if err != nil { return nil, err } @@ -651,14 +649,14 @@ func chkMgmtIPandEnableForwarding(networkName string, hnsEndpoint *hcsshim.HNSEn } ourEpAddr := hnsEndpoint.IPAddress.String() - netInterface, err := netHelper.GetInterfaceByIP(ourEpAddr) + netInterface, err := lookupManagementIface(net.ParseIP(ourEpAddr), logger) if err != nil { logger.WithError(err).Errorf("Unable to find interface matching our host endpoint [%v]", ourEpAddr) return nil, err } logger.Infof("Found Interface with IP[%s]: %v", ourEpAddr, netInterface) - err = enableForwarding(netHelper, netInterface, logger) + err = enableForwarding(netInterface, logger) if err != nil { return nil, err } @@ -666,9 +664,10 @@ func chkMgmtIPandEnableForwarding(networkName string, hnsEndpoint *hcsshim.HNSEn return network, nil } -func enableForwarding(netHelper netsh.Interface, netInterface netsh.Ipv4Interface, logger *logrus.Entry) error { - interfaceIdx := strconv.Itoa(netInterface.Idx) - if err := netHelper.EnableForwarding(interfaceIdx); err != nil { +func enableForwarding(netInterface net.Interface, logger *logrus.Entry) error { + interfaceIdx := strconv.Itoa(netInterface.Index) + cmd := fmt.Sprintf("Set-NetIPInterface -ifIndex %s -AddressFamily IPv4 -Forwarding Enabled", interfaceIdx) + if _, _, err := winutils.Powershell(cmd); err != nil { logger.WithError(err).Errorf("Unable to enable forwarding on [%v] index [%v]", netInterface.Name, interfaceIdx) return err @@ -959,6 +958,31 @@ func cleanUpEndpointByName(endpointName string, logger *logrus.Entry, isDockerV1 } } +func lookupManagementIface(mgmtIP net.IP, logger *logrus.Entry) (net.Interface, error) { + interfaces, err := net.Interfaces() + if err != nil { + logger.WithError(err).Error("Failed to look up host interfaces") + return net.Interface{}, err + } + + for _, iface := range interfaces { + addrs, err := iface.Addrs() + if err != nil { + logger.WithError(err).WithField("iface", iface.Name).Error( + "Failed to look up host interface addresses") + return net.Interface{}, err + } + for _, addr := range addrs { + if ipAddr, ok := addr.(*net.IPNet); ok { + if ipAddr.Contains(mgmtIP) { + return iface, nil + } + } + } + } + return net.Interface{}, fmt.Errorf("couldn't find an interface matching management IP %s", mgmtIP.String()) +} + func lookupManagementAddr(mgmtIP net.IP, logger *logrus.Entry) (*net.IPNet, error) { interfaces, err := net.Interfaces() if err != nil { diff --git a/cni-plugin/pkg/install/install.go b/cni-plugin/pkg/install/install.go index 1f0c72155a8..cecc2ec9ea6 100644 --- a/cni-plugin/pkg/install/install.go +++ b/cni-plugin/pkg/install/install.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ import ( "github.com/nmrshll/go-cp" "github.com/sirupsen/logrus" "go.etcd.io/etcd/client/pkg/v3/fileutil" - "k8s.io/client-go/rest" "github.com/projectcalico/calico/libcalico-go/lib/logutils" @@ -118,11 +117,8 @@ func loadConfig() config { } func Install(version string) error { - // Configure logging before anything else. - logrus.SetFormatter(&logutils.Formatter{Component: "cni-installer"}) - - // Install a hook that adds file/line no information. - logrus.AddHook(&logutils.ContextHook{}) + // Set up logging formatting. + logutils.ConfigureFormatter("cni-installer") // Clean up any existing binaries / config / assets. if err := os.RemoveAll(winutils.GetHostPath("/host/etc/cni/net.d/calico-tls")); err != nil && !os.IsNotExist(err) { diff --git a/cni-plugin/pkg/ipamplugin/ipam_plugin.go b/cni-plugin/pkg/ipamplugin/ipam_plugin.go index 06e4e5109c4..4fab556c55c 100644 --- a/cni-plugin/pkg/ipamplugin/ipam_plugin.go +++ b/cni-plugin/pkg/ipamplugin/ipam_plugin.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2015-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,11 +29,9 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types" cniv1 "github.com/containernetworking/cni/pkg/types/100" cniSpecVersion "github.com/containernetworking/cni/pkg/version" - "github.com/gofrs/flock" - "github.com/sirupsen/logrus" - v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/sirupsen/logrus" "github.com/projectcalico/calico/cni-plugin/internal/pkg/utils" "github.com/projectcalico/calico/cni-plugin/pkg/types" @@ -48,10 +46,7 @@ import ( func Main(version string) { // Set up logging formatting. - logrus.SetFormatter(&logutils.Formatter{}) - - // Install a hook that adds file/line no information. - logrus.AddHook(&logutils.ContextHook{}) + logutils.ConfigureFormatter("ipam") // Display the version on "-v", otherwise just delegate to the skel code. // Use a new flag set so as not to conflict with existing libraries which use "flag" diff --git a/cni-plugin/pkg/plugin/plugin.go b/cni-plugin/pkg/plugin/plugin.go index 2bbf8b89ce2..f73039eca96 100644 --- a/cni-plugin/pkg/plugin/plugin.go +++ b/cni-plugin/pkg/plugin/plugin.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2015-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + package plugin import ( @@ -33,15 +34,12 @@ import ( cniSpecVersion "github.com/containernetworking/cni/pkg/version" "github.com/containernetworking/plugins/pkg/ipam" "github.com/mcuadros/go-version" + api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "github.com/projectcalico/calico/libcalico-go/lib/winutils" - - api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" - "github.com/projectcalico/calico/cni-plugin/internal/pkg/utils" "github.com/projectcalico/calico/cni-plugin/pkg/dataplane" "github.com/projectcalico/calico/cni-plugin/pkg/k8s" @@ -51,6 +49,7 @@ import ( cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/options" + "github.com/projectcalico/calico/libcalico-go/lib/winutils" ) const testConnectionTimeout = 2 * time.Second @@ -156,7 +155,7 @@ func cmdAdd(args *skel.CmdArgs) (err error) { // present both. msg = fmt.Sprintf("%s: error=%s", msg, err) } - err = fmt.Errorf(msg) + err = fmt.Errorf("%s", msg) } if err != nil { logrus.WithError(err).Error("Final result of CNI ADD was an error.") @@ -573,7 +572,7 @@ func cmdDel(args *skel.CmdArgs) (err error) { // present both. msg = fmt.Sprintf("%s: error=%s", msg, err) } - err = fmt.Errorf(msg) + err = fmt.Errorf("%s", msg) } if err != nil { logrus.WithError(err).Error("Final result of CNI DEL was an error.") @@ -691,10 +690,7 @@ func cmdDummyCheck(args *skel.CmdArgs) (err error) { func Main(version string) { // Set up logging formatting. - logrus.SetFormatter(&logutils.Formatter{}) - - // Install a hook that adds file/line no information. - logrus.AddHook(&logutils.ContextHook{}) + logutils.ConfigureFormatter("cni-plugin") // Use a new flag set so as not to conflict with existing libraries which use "flag" flagSet := flag.NewFlagSet("Calico", flag.ExitOnError) diff --git a/cni-plugin/tests/calico_cni_k8s_test.go b/cni-plugin/tests/calico_cni_k8s_test.go index 4e64b09c77c..dbf545c2f19 100644 --- a/cni-plugin/tests/calico_cni_k8s_test.go +++ b/cni-plugin/tests/calico_cni_k8s_test.go @@ -43,6 +43,7 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/ipam" "github.com/projectcalico/calico/libcalico-go/lib/names" cnet "github.com/projectcalico/calico/libcalico-go/lib/net" + "github.com/projectcalico/calico/libcalico-go/lib/netlinkutils" "github.com/projectcalico/calico/libcalico-go/lib/options" ) @@ -313,7 +314,9 @@ var _ = Describe("Kubernetes CNI tests", func() { Expect(err).ShouldNot(HaveOccurred()) // Assert if the host side route is programmed correctly. - hostRoutes, err := netlink.RouteList(hostVeth, syscall.AF_INET) + nlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) + Expect(err).ShouldNot(HaveOccurred()) + hostRoutes, err := netlinkutils.RouteListRetryEINTR(nlHandle, hostVeth, syscall.AF_INET) Expect(err).ShouldNot(HaveOccurred()) Expect(hostRoutes[0]).Should(Equal(netlink.Route{ LinkIndex: hostVeth.Attrs().Index, diff --git a/cni-plugin/tests/calico_cni_test.go b/cni-plugin/tests/calico_cni_test.go index fa488daebbd..3cad1e89030 100644 --- a/cni-plugin/tests/calico_cni_test.go +++ b/cni-plugin/tests/calico_cni_test.go @@ -29,6 +29,7 @@ import ( libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" "github.com/projectcalico/calico/libcalico-go/lib/names" + "github.com/projectcalico/calico/libcalico-go/lib/netlinkutils" "github.com/projectcalico/calico/libcalico-go/lib/options" ) @@ -157,7 +158,9 @@ var _ = Describe("CalicoCni", func() { Expect(err).ShouldNot(HaveOccurred()) // Assert if the host side route is programmed correctly. - hostRoutes, err := netlink.RouteList(hostVeth, syscall.AF_INET) + nlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) + Expect(err).ShouldNot(HaveOccurred()) + hostRoutes, err := netlinkutils.RouteListRetryEINTR(nlHandle, hostVeth, syscall.AF_INET) Expect(err).ShouldNot(HaveOccurred()) Expect(hostRoutes[0]).Should(Equal(netlink.Route{ LinkIndex: hostVeth.Attrs().Index, diff --git a/confd/Makefile b/confd/Makefile index b734085db3b..3a38065adaf 100644 --- a/confd/Makefile +++ b/confd/Makefile @@ -104,7 +104,7 @@ ut: bin/kubectl: - curl -sSf -L --retry 5 https://storage.googleapis.com/kubernetes-release/release/$(K8S_VERSION)/bin/linux/$(ARCH)/kubectl -o $@ + curl -sSf -L --retry 5 https://dl.k8s.io/release/$(K8S_VERSION)/bin/linux/$(ARCH)/kubectl -o $@ chmod +x $@ bin/bird bin/bird6: diff --git a/confd/etc/calico/confd/templates/bird6_ipam.cfg.template b/confd/etc/calico/confd/templates/bird6_ipam.cfg.template index 28b5a19599d..fc65d01d3c2 100644 --- a/confd/etc/calico/confd/templates/bird6_ipam.cfg.template +++ b/confd/etc/calico/confd/templates/bird6_ipam.cfg.template @@ -18,6 +18,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -26,6 +35,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); {{- $static_key := "/staticroutesv6"}} diff --git a/confd/etc/calico/confd/templates/bird_ipam.cfg.template b/confd/etc/calico/confd/templates/bird_ipam.cfg.template index 10905d8060e..803c46e995f 100644 --- a/confd/etc/calico/confd/templates/bird_ipam.cfg.template +++ b/confd/etc/calico/confd/templates/bird_ipam.cfg.template @@ -18,6 +18,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -26,6 +35,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); {{- $static_key := "/staticroutes"}} diff --git a/confd/pkg/backends/calico/client.go b/confd/pkg/backends/calico/client.go index 605a2eab957..4d9c17ed7cc 100644 --- a/confd/pkg/backends/calico/client.go +++ b/confd/pkg/backends/calico/client.go @@ -1266,9 +1266,13 @@ func (c *client) getServiceExternalIPsKVPair(v3res *apiv3.BGPConfiguration, key if v3res != nil && v3res.Spec.ServiceExternalIPs != nil && len(v3res.Spec.ServiceExternalIPs) != 0 { // We wrap each Service external IP in a ServiceExternalIPBlock struct to // achieve the desired API structure, unpack that. - ipCidrs := make([]string, len(v3res.Spec.ServiceExternalIPs)) - for i, ipBlock := range v3res.Spec.ServiceExternalIPs { - ipCidrs[i] = ipBlock.CIDR + ipCidrs := make([]string, 0, len(v3res.Spec.ServiceExternalIPs)) + for _, ipBlock := range v3res.Spec.ServiceExternalIPs { + if ipBlock.CIDR == "" { + // The CRD allows CIDR to be optional so we just ignore empty CIDRs. + continue + } + ipCidrs = append(ipCidrs, ipBlock.CIDR) } c.updateCache(api.UpdateTypeKVUpdated, getKVPair(svcExternalIPKey, strings.Join(ipCidrs, ","))) } else { @@ -1281,9 +1285,13 @@ func (c *client) getServiceLoadBalancerIPsKVPair(v3res *apiv3.BGPConfiguration, svcLoadBalancerIPKey := getBGPConfigKey("svc_loadbalancer_ips", key) if v3res != nil && v3res.Spec.ServiceLoadBalancerIPs != nil && len(v3res.Spec.ServiceLoadBalancerIPs) != 0 { - ipCidrs := make([]string, len(v3res.Spec.ServiceLoadBalancerIPs)) - for i, ipBlock := range v3res.Spec.ServiceLoadBalancerIPs { - ipCidrs[i] = ipBlock.CIDR + ipCidrs := make([]string, 0, len(v3res.Spec.ServiceLoadBalancerIPs)) + for _, ipBlock := range v3res.Spec.ServiceLoadBalancerIPs { + if ipBlock.CIDR == "" { + // The CRD allows CIDR to be optional so we just ignore empty CIDRs. + continue + } + ipCidrs = append(ipCidrs, ipBlock.CIDR) } c.updateCache(api.UpdateTypeKVUpdated, getKVPair(svcLoadBalancerIPKey, strings.Join(ipCidrs, ","))) } else { @@ -1304,9 +1312,13 @@ func (c *client) getServiceClusterIPsKVPair(v3res *apiv3.BGPConfiguration, key i if v3res != nil && v3res.Spec.ServiceClusterIPs != nil && len(v3res.Spec.ServiceClusterIPs) != 0 { // We wrap each Service Cluster IP in a ServiceClusterIPBlock to // achieve the desired API structure. This unpacks that. - ipCidrs := make([]string, len(v3res.Spec.ServiceClusterIPs)) - for i, ipBlock := range v3res.Spec.ServiceClusterIPs { - ipCidrs[i] = ipBlock.CIDR + ipCidrs := make([]string, 0, len(v3res.Spec.ServiceClusterIPs)) + for _, ipBlock := range v3res.Spec.ServiceClusterIPs { + if ipBlock.CIDR == "" { + // The CRD allows CIDR to be optional so we just ignore empty CIDRs. + continue + } + ipCidrs = append(ipCidrs, ipBlock.CIDR) } c.updateCache(api.UpdateTypeKVUpdated, getKVPair(svcInternalIPKey, strings.Join(ipCidrs, ","))) } else { diff --git a/confd/pkg/log/log.go b/confd/pkg/log/log.go index e54e9fc072a..df8affa9abe 100644 --- a/confd/pkg/log/log.go +++ b/confd/pkg/log/log.go @@ -14,8 +14,8 @@ import ( ) func init() { - log.AddHook(logutils.ContextHook{}) - log.SetFormatter(&logutils.Formatter{Component: "confd"}) + // Set up logging formatting. + logutils.ConfigureFormatter("confd") } // SetLevel sets the log level. Valid levels are panic, fatal, error, warn, info and debug. diff --git a/confd/pkg/resource/template/template_funcs.go b/confd/pkg/resource/template/template_funcs.go index 0012cbaa868..35aa387350d 100644 --- a/confd/pkg/resource/template/template_funcs.go +++ b/confd/pkg/resource/template/template_funcs.go @@ -65,7 +65,7 @@ func filterStatement(fields filterArgs) (string, error) { if fields.operator == "" { return "", fmt.Errorf("operator not included in BGPFilter") } - cidrCondition, err := filterMatchCIDR(fields.cidr, fields.operator) + cidrCondition, err := filterMatchCIDR(fields.cidr, fields.prefixLengthV4, fields.prefixLengthV6, fields.operator) if err != nil { return "", err } @@ -111,11 +111,49 @@ var ( } ) -func filterMatchCIDR(cidr string, operator v3.BGPFilterMatchOperator) (string, error) { +func filterMatchPrefixLength(cidr string, prefixMin, prefixMax *int32) (string, error) { + cidrIP, cidrNet, err := net.ParseCIDR(cidr) + if err != nil { + return "", fmt.Errorf("unexpected error when parsing cidr %s: %s", cidr, err) + } + + mask, _ := cidrNet.Mask.Size() + minLength := int32(mask) + // default for ipv4 + maxLength := int32(32) + + // check for ipv6 IP + if cidrIP.To4() == nil { + maxLength = 128 + } + + if prefixMin != nil { + minLength = max(minLength, *prefixMin) + } + if prefixMax != nil { + maxLength = min(maxLength, *prefixMax) + } + + return fmt.Sprintf("[ %s{%d,%d} ]", cidr, minLength, maxLength), nil +} + +func filterMatchCIDR(cidr string, prefixLengthV4 *v3.BGPFilterPrefixLengthV4, prefixLengthV6 *v3.BGPFilterPrefixLengthV6, operator v3.BGPFilterMatchOperator) (string, error) { op, ok := operatorLUT[operator] if !ok { return "", fmt.Errorf("unexpected operator found in BGPFilter: %s", operator) } + + var err error + if prefixLengthV4 != nil { + cidr, err = filterMatchPrefixLength(cidr, prefixLengthV4.Min, prefixLengthV4.Max) + } else if prefixLengthV6 != nil { + cidr, err = filterMatchPrefixLength(cidr, prefixLengthV6.Min, prefixLengthV6.Max) + } + + if err != nil { + return "", err + } + return fmt.Sprintf("(net %s %s)", op, cidr), nil } @@ -155,11 +193,13 @@ func BGPFilterFunctionName(filterName, direction, version string) (string, error } type filterArgs struct { - operator v3.BGPFilterMatchOperator - cidr string - source v3.BGPFilterMatchSource - iface string - action v3.BGPFilterAction + operator v3.BGPFilterMatchOperator + cidr string + prefixLengthV4 *v3.BGPFilterPrefixLengthV4 + prefixLengthV6 *v3.BGPFilterPrefixLengthV6 + source v3.BGPFilterMatchSource + iface string + action v3.BGPFilterAction } // BGPFilterBIRDFuncs generates a set of BIRD functions for BGPFilter resources that have been packaged into KVPairs. @@ -261,21 +301,23 @@ func BGPFilterBIRDFuncs(pairs memkv.KVPairs, version int) ([]string, error) { if v4Selected { for _, importV4 := range importFiltersV4 { ruleFields = append(ruleFields, filterArgs{ - operator: importV4.MatchOperator, - cidr: importV4.CIDR, - source: importV4.Source, - iface: importV4.Interface, - action: importV4.Action, + operator: importV4.MatchOperator, + cidr: importV4.CIDR, + prefixLengthV4: importV4.PrefixLength, + source: importV4.Source, + iface: importV4.Interface, + action: importV4.Action, }) } } else { for _, importV6 := range importFiltersV6 { ruleFields = append(ruleFields, filterArgs{ - operator: importV6.MatchOperator, - cidr: importV6.CIDR, - source: importV6.Source, - iface: importV6.Interface, - action: importV6.Action, + operator: importV6.MatchOperator, + cidr: importV6.CIDR, + prefixLengthV6: importV6.PrefixLength, + source: importV6.Source, + iface: importV6.Interface, + action: importV6.Action, }) } } @@ -306,21 +348,23 @@ func BGPFilterBIRDFuncs(pairs memkv.KVPairs, version int) ([]string, error) { if v4Selected { for _, exportV4 := range exportFiltersV4 { ruleFields = append(ruleFields, filterArgs{ - operator: exportV4.MatchOperator, - cidr: exportV4.CIDR, - source: exportV4.Source, - iface: exportV4.Interface, - action: exportV4.Action, + operator: exportV4.MatchOperator, + cidr: exportV4.CIDR, + prefixLengthV4: exportV4.PrefixLength, + source: exportV4.Source, + iface: exportV4.Interface, + action: exportV4.Action, }) } } else { for _, exportV6 := range exportFiltersV6 { ruleFields = append(ruleFields, filterArgs{ - operator: exportV6.MatchOperator, - cidr: exportV6.CIDR, - source: exportV6.Source, - iface: exportV6.Interface, - action: exportV6.Action, + operator: exportV6.MatchOperator, + cidr: exportV6.CIDR, + prefixLengthV6: exportV6.PrefixLength, + source: exportV6.Source, + iface: exportV6.Interface, + action: exportV6.Action, }) } } diff --git a/confd/pkg/resource/template/template_funcs_test.go b/confd/pkg/resource/template/template_funcs_test.go index e103f3f6639..cea00a6f6bd 100644 --- a/confd/pkg/resource/template/template_funcs_test.go +++ b/confd/pkg/resource/template/template_funcs_test.go @@ -59,8 +59,10 @@ func Test_BGPFilterBIRDFuncs(t *testing.T) { ImportV4: []v3.BGPFilterRuleV4{ {Action: "Accept", Source: "RemotePeers", Interface: "vxlan.calico", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, {Action: "Reject", Source: "RemotePeers", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, + {Action: "Reject", Source: "RemotePeers", MatchOperator: "NotIn", CIDR: "55.4.0.0/16", PrefixLength: &v3.BGPFilterPrefixLengthV4{Min: int32Helper(16), Max: int32Helper(24)}}, {Action: "Reject", Interface: "eth0", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, {Action: "Accept", Interface: "eth0", Source: "RemotePeers"}, + {Action: "Reject", Interface: "eth0", Source: "RemotePeers", PrefixLength: &v3.BGPFilterPrefixLengthV4{Min: int32Helper(16), Max: int32Helper(24)}}, {Action: "Reject", MatchOperator: "Equal", CIDR: "44.4.0.0/16"}, {Action: "Accept", Source: "RemotePeers"}, {Action: "Reject", Interface: "extraiface"}, @@ -69,6 +71,7 @@ func Test_BGPFilterBIRDFuncs(t *testing.T) { ExportV4: []v3.BGPFilterRuleV4{ {Action: "Reject", Source: "RemotePeers", Interface: "vxlan.calico", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, {Action: "Reject", Source: "RemotePeers", MatchOperator: "NotIn", CIDR: "88.7.0.0/16"}, + {Action: "Reject", Source: "RemotePeers", MatchOperator: "NotIn", CIDR: "88.7.0.0/16", PrefixLength: &v3.BGPFilterPrefixLengthV4{Max: int32Helper(24)}}, {Action: "Accept", Interface: "eth0", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, {Action: "Reject", Interface: "eth0", Source: "RemotePeers"}, {Action: "Accept", MatchOperator: "In", CIDR: "77.7.0.0/16"}, @@ -77,21 +80,25 @@ func Test_BGPFilterBIRDFuncs(t *testing.T) { {Action: "Reject"}, }, ImportV6: []v3.BGPFilterRuleV6{ - {Action: "Reject", Source: "RemotePeers", Interface: "vxlan.calico", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, + {Action: "Reject", Source: "RemotePeers", Interface: "vxlan.calico", MatchOperator: "NotIn", CIDR: "7000:1::0/64"}, {Action: "Reject", Source: "RemotePeers", MatchOperator: "NotEqual", CIDR: "8000:1::0/64"}, - {Action: "Accept", Interface: "eth0", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, + {Action: "Accept", Interface: "eth0", MatchOperator: "NotIn", CIDR: "6000:1::0/64"}, + {Action: "Accept", Interface: "eth0", MatchOperator: "NotIn", CIDR: "6000:1::0/64", PrefixLength: &v3.BGPFilterPrefixLengthV6{Min: int32Helper(96)}}, {Action: "Reject", Interface: "eth0", Source: "RemotePeers"}, {Action: "Accept", MatchOperator: "NotEqual", CIDR: "7000:1::0/64"}, + {Action: "Accept", MatchOperator: "NotEqual", CIDR: "7000:1::0/64", PrefixLength: &v3.BGPFilterPrefixLengthV6{Max: int32Helper(96)}}, {Action: "Accept", Source: "RemotePeers"}, {Action: "Accept", Interface: "extraiface"}, {Action: "Reject"}, }, ExportV6: []v3.BGPFilterRuleV6{ - {Action: "Accept", Source: "RemotePeers", Interface: "vxlan.calico", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, + {Action: "Accept", Source: "RemotePeers", Interface: "vxlan.calico", MatchOperator: "NotIn", CIDR: "b000:1::0/64"}, {Action: "Reject", Source: "RemotePeers", MatchOperator: "NotIn", CIDR: "a000:1::0/64"}, - {Action: "Reject", Interface: "eth0", MatchOperator: "NotIn", CIDR: "55.4.0.0/16"}, + {Action: "Reject", Interface: "eth0", MatchOperator: "NotIn", CIDR: "c000:1::0/64"}, + {Action: "Reject", Interface: "eth0", MatchOperator: "NotIn", CIDR: "c000:1::0/64", PrefixLength: &v3.BGPFilterPrefixLengthV6{Min: int32Helper(120), Max: int32Helper(128)}}, {Action: "Accept", Interface: "eth0", Source: "RemotePeers"}, {Action: "Accept", MatchOperator: "NotIn", CIDR: "9000:1::0/64"}, + {Action: "Accept", MatchOperator: "NotIn", CIDR: "9000:1::0/64", PrefixLength: &v3.BGPFilterPrefixLengthV6{Min: int32Helper(96), Max: int32Helper(120)}}, {Action: "Accept", Source: "RemotePeers"}, {Action: "Reject", Interface: "extraiface"}, {Action: "Reject"}, @@ -102,8 +109,10 @@ func Test_BGPFilterBIRDFuncs(t *testing.T) { "function 'bgp_test-bgpfilter_importFilterV4'() {", " if ((net !~ 55.4.0.0/16)&&((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"vxlan.calico\"))) then { accept; }", " if ((net !~ 55.4.0.0/16)&&((defined(source))&&(source ~ [ RTS_BGP ]))) then { reject; }", + " if ((net !~ [ 55.4.0.0/16{16,24} ])&&((defined(source))&&(source ~ [ RTS_BGP ]))) then { reject; }", " if ((net !~ 55.4.0.0/16)&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { accept; }", + " if (((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", " if ((net = 44.4.0.0/16)) then { reject; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))) then { accept; }", " if (((defined(ifname))&&(ifname ~ \"extraiface\"))) then { reject; }", @@ -112,6 +121,7 @@ func Test_BGPFilterBIRDFuncs(t *testing.T) { "function 'bgp_test-bgpfilter_exportFilterV4'() {", " if ((net !~ 55.4.0.0/16)&&((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"vxlan.calico\"))) then { reject; }", " if ((net !~ 88.7.0.0/16)&&((defined(source))&&(source ~ [ RTS_BGP ]))) then { reject; }", + " if ((net !~ [ 88.7.0.0/16{16,24} ])&&((defined(source))&&(source ~ [ RTS_BGP ]))) then { reject; }", " if ((net !~ 55.4.0.0/16)&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { accept; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", " if ((net ~ 77.7.0.0/16)) then { accept; }", @@ -123,21 +133,25 @@ func Test_BGPFilterBIRDFuncs(t *testing.T) { expectedBIRDCfgStrV6 := []string{ "# v6 BGPFilter test-bgpfilter", "function 'bgp_test-bgpfilter_importFilterV6'() {", - " if ((net !~ 55.4.0.0/16)&&((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"vxlan.calico\"))) then { reject; }", + " if ((net !~ 7000:1::0/64)&&((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"vxlan.calico\"))) then { reject; }", " if ((net != 8000:1::0/64)&&((defined(source))&&(source ~ [ RTS_BGP ]))) then { reject; }", - " if ((net !~ 55.4.0.0/16)&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { accept; }", + " if ((net !~ 6000:1::0/64)&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { accept; }", + " if ((net !~ [ 6000:1::0/64{96,128} ])&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { accept; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", " if ((net != 7000:1::0/64)) then { accept; }", + " if ((net != [ 7000:1::0/64{64,96} ])) then { accept; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))) then { accept; }", " if (((defined(ifname))&&(ifname ~ \"extraiface\"))) then { accept; }", " reject;", "}", "function 'bgp_test-bgpfilter_exportFilterV6'() {", - " if ((net !~ 55.4.0.0/16)&&((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"vxlan.calico\"))) then { accept; }", + " if ((net !~ b000:1::0/64)&&((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"vxlan.calico\"))) then { accept; }", " if ((net !~ a000:1::0/64)&&((defined(source))&&(source ~ [ RTS_BGP ]))) then { reject; }", - " if ((net !~ 55.4.0.0/16)&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", + " if ((net !~ c000:1::0/64)&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", + " if ((net !~ [ c000:1::0/64{120,128} ])&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { reject; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))&&((defined(ifname))&&(ifname ~ \"eth0\"))) then { accept; }", " if ((net !~ 9000:1::0/64)) then { accept; }", + " if ((net !~ [ 9000:1::0/64{96,120} ])) then { accept; }", " if (((defined(source))&&(source ~ [ RTS_BGP ]))) then { accept; }", " if (((defined(ifname))&&(ifname ~ \"extraiface\"))) then { reject; }", " reject;", @@ -186,3 +200,7 @@ func Test_ValidateHashToIpv4Method(t *testing.T) { t.Errorf("Expected %s to equal %s", expectedRouterId, actualRouterId) } } + +func int32Helper(i int32) *int32 { + return &i +} diff --git a/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/export_only/explicit_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/export_only/global_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step1/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/filter_deletion/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/filter_names/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/filter_names/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/filter_names/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/filter_names/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/filter_names/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/filter_names/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/filter_names/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/filter_names/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/import_only/explicit_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/import_only/global_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/match_interface/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/match_interface/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/match_interface/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/match_interface/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/match_interface/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/match_interface/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/match_interface/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/match_interface/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/match_operators/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/match_operators/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/match_operators/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/match_operators/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/match_operators/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/match_operators/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/match_operators/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/match_operators/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/match_source/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/match_source/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/match_source/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/match_source/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/match_source/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/match_source/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/match_source/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/match_source/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/multi_filter/explicit_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/multi_filter/global_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/node_mesh/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/node_mesh/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/node_mesh/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/node_mesh/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/node_mesh/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/node_mesh/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/node_mesh/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/node_mesh/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/single_filter/explicit_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/single_filter/global_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v4_only/explicit_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v4_only/global_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v6_only/explicit_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird6_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird_ipam.cfg b/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird_ipam.cfg +++ b/confd/tests/compiled_templates/bgpfilter/v6_only/global_peer/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/global-external/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/global-external/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/global-external/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/global-external/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/global-external/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/global-external/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/global-external/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/global-external/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird6_ipam.cfg index 4fab5f8d396..6fd518a50a9 100644 --- a/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/global-ipv6/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/global/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/global/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/global/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/global/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/global/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/global/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/global/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/global/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/keepnexthop-global/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/keepnexthop/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/local-as-global/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/local-as-global/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/local-as-global/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/local-as-global/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/local-as-global/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/local-as-global/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/local-as-global/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/local-as-global/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/local-as/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/local-as/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/local-as/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/local-as/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/local-as/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/local-as/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/local-as/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/local-as/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/route_reflector/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/route_reflector/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/route_reflector/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/route_reflector/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/route_reflector/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/route_reflector/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/route_reflector/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/route_reflector/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/route_reflector_v6_by_ip/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/selectors/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/selectors/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/selectors/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/selectors/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/selectors/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/selectors/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/selectors/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/selectors/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/selectors/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/specific_node/bird6_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/specific_node/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/explicit_peering/specific_node/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/specific_node/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/explicit_peering/specific_node/bird_ipam.cfg b/confd/tests/compiled_templates/explicit_peering/specific_node/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/explicit_peering/specific_node/bird_ipam.cfg +++ b/confd/tests/compiled_templates/explicit_peering/specific_node/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ignored_interfaces/bird6_ipam.cfg b/confd/tests/compiled_templates/ignored_interfaces/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/ignored_interfaces/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/ignored_interfaces/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ignored_interfaces/bird_ipam.cfg b/confd/tests/compiled_templates/ignored_interfaces/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/ignored_interfaces/bird_ipam.cfg +++ b/confd/tests/compiled_templates/ignored_interfaces/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/bgp-export/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/bgp-export/bird6_ipam.cfg index 6269e16308b..2706563a32a 100644 --- a/confd/tests/compiled_templates/mesh/bgp-export/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/bgp-export/bird6_ipam.cfg @@ -15,6 +15,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -23,6 +32,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/bgp-export/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/bgp-export/bird_ipam.cfg index 9098eb06830..6f9ad064e34 100644 --- a/confd/tests/compiled_templates/mesh/bgp-export/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/bgp-export/bird_ipam.cfg @@ -15,6 +15,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -23,6 +32,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/communities/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/communities/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/communities/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/communities/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/communities/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/communities/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/communities/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/communities/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/communities/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/communities/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/communities/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/communities/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/communities/step2/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/communities/step2/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/communities/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/communities/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/hash/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/hash/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/hash/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/hash/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/hash/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/hash/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/hash/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/hash/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/ipip-always/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/ipip-always/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/ipip-always/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/ipip-always/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/ipip-always/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/ipip-always/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/mesh/ipip-always/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/ipip-always/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird_ipam.cfg index f7dd96ff075..57300f8a0a5 100644 --- a/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/ipip-cross-subnet/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/ipip-off/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/ipip-off/bird6_ipam.cfg index 4fab5f8d396..6fd518a50a9 100644 --- a/confd/tests/compiled_templates/mesh/ipip-off/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/ipip-off/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/ipip-off/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/ipip-off/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/ipip-off/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/ipip-off/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/password/step1/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/password/step1/bird6_ipam.cfg index 4fab5f8d396..6fd518a50a9 100644 --- a/confd/tests/compiled_templates/mesh/password/step1/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/password/step1/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/password/step1/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/password/step1/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/password/step1/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/password/step1/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/password/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/password/step2/bird6_ipam.cfg index 4fab5f8d396..6fd518a50a9 100644 --- a/confd/tests/compiled_templates/mesh/password/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/password/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/password/step2/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/password/step2/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/password/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/password/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/password/step3/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/password/step3/bird6_ipam.cfg index 4fab5f8d396..6fd518a50a9 100644 --- a/confd/tests/compiled_templates/mesh/password/step3/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/password/step3/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/password/step3/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/password/step3/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/password/step3/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/password/step3/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/restart-time/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/restart-time/bird6_ipam.cfg index 4fab5f8d396..6fd518a50a9 100644 --- a/confd/tests/compiled_templates/mesh/restart-time/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/restart-time/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/restart-time/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/restart-time/bird_ipam.cfg index 45e216e04a7..6bf2288cb65 100644 --- a/confd/tests/compiled_templates/mesh/restart-time/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/restart-time/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/route-reflector-mesh-enabled/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird6_ipam.cfg index 6e2c9ae818d..1a5c1e90049 100644 --- a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird_ipam.cfg index e7f629ee1ae..025d4909edb 100644 --- a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes-exclude-node/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird_ipam.cfg index 346212966d2..ddc693f28ff 100644 --- a/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes-no-ipv4-address/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes/bird6_ipam.cfg index 37a5c4c75dd..7e615a4af05 100644 --- a/confd/tests/compiled_templates/mesh/static-routes/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes/bird_ipam.cfg index 65478831737..7462b303165 100644 --- a/confd/tests/compiled_templates/mesh/static-routes/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/mesh/static-routes/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/static-routes/step2/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/static-routes/step2/bird_ipam.cfg index 23a07585f21..8c4453f41a1 100644 --- a/confd/tests/compiled_templates/mesh/static-routes/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/static-routes/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/vxlan-always/bird6_ipam.cfg b/confd/tests/compiled_templates/mesh/vxlan-always/bird6_ipam.cfg index 52b7f72201c..1bc8a213447 100644 --- a/confd/tests/compiled_templates/mesh/vxlan-always/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/vxlan-always/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/mesh/vxlan-always/bird_ipam.cfg b/confd/tests/compiled_templates/mesh/vxlan-always/bird_ipam.cfg index 4a04effdf63..22bf027b62f 100644 --- a/confd/tests/compiled_templates/mesh/vxlan-always/bird_ipam.cfg +++ b/confd/tests/compiled_templates/mesh/vxlan-always/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password-deadlock/bird6_ipam.cfg b/confd/tests/compiled_templates/password-deadlock/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password-deadlock/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password-deadlock/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password-deadlock/bird_ipam.cfg b/confd/tests/compiled_templates/password-deadlock/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password-deadlock/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password-deadlock/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step1/bird6_ipam.cfg b/confd/tests/compiled_templates/password/step1/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password/step1/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password/step1/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step1/bird_ipam.cfg b/confd/tests/compiled_templates/password/step1/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password/step1/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password/step1/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/password/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step2/bird_ipam.cfg b/confd/tests/compiled_templates/password/step2/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step3/bird6_ipam.cfg b/confd/tests/compiled_templates/password/step3/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password/step3/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password/step3/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step3/bird_ipam.cfg b/confd/tests/compiled_templates/password/step3/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password/step3/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password/step3/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step4/bird6_ipam.cfg b/confd/tests/compiled_templates/password/step4/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password/step4/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password/step4/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step4/bird_ipam.cfg b/confd/tests/compiled_templates/password/step4/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password/step4/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password/step4/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step5/bird6_ipam.cfg b/confd/tests/compiled_templates/password/step5/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password/step5/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password/step5/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step5/bird_ipam.cfg b/confd/tests/compiled_templates/password/step5/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password/step5/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password/step5/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step6/bird6_ipam.cfg b/confd/tests/compiled_templates/password/step6/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/password/step6/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/password/step6/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/password/step6/bird_ipam.cfg b/confd/tests/compiled_templates/password/step6/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/password/step6/bird_ipam.cfg +++ b/confd/tests/compiled_templates/password/step6/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/reachable_by/global_peers/bird6_ipam.cfg b/confd/tests/compiled_templates/reachable_by/global_peers/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/reachable_by/global_peers/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/reachable_by/global_peers/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/reachable_by/global_peers/bird_ipam.cfg b/confd/tests/compiled_templates/reachable_by/global_peers/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/reachable_by/global_peers/bird_ipam.cfg +++ b/confd/tests/compiled_templates/reachable_by/global_peers/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/reachable_by/route_reflectors/bird6_ipam.cfg b/confd/tests/compiled_templates/reachable_by/route_reflectors/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/reachable_by/route_reflectors/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/reachable_by/route_reflectors/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/reachable_by/route_reflectors/bird_ipam.cfg b/confd/tests/compiled_templates/reachable_by/route_reflectors/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/reachable_by/route_reflectors/bird_ipam.cfg +++ b/confd/tests/compiled_templates/reachable_by/route_reflectors/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird6_ipam.cfg b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird_ipam.cfg b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird_ipam.cfg +++ b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step1/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird6_ipam.cfg b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird_ipam.cfg b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird_ipam.cfg +++ b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step2/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird6_ipam.cfg b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird_ipam.cfg b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird_ipam.cfg +++ b/confd/tests/compiled_templates/sourceaddr_gracefulrestart/step3/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ttl_security/explicit_node/bird6_ipam.cfg b/confd/tests/compiled_templates/ttl_security/explicit_node/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/ttl_security/explicit_node/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/ttl_security/explicit_node/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ttl_security/explicit_node/bird_ipam.cfg b/confd/tests/compiled_templates/ttl_security/explicit_node/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/ttl_security/explicit_node/bird_ipam.cfg +++ b/confd/tests/compiled_templates/ttl_security/explicit_node/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ttl_security/global/bird6_ipam.cfg b/confd/tests/compiled_templates/ttl_security/global/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/ttl_security/global/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/ttl_security/global/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ttl_security/global/bird_ipam.cfg b/confd/tests/compiled_templates/ttl_security/global/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/ttl_security/global/bird_ipam.cfg +++ b/confd/tests/compiled_templates/ttl_security/global/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ttl_security/peer_selector/bird6_ipam.cfg b/confd/tests/compiled_templates/ttl_security/peer_selector/bird6_ipam.cfg index 67327e452b9..d7daa3928e5 100644 --- a/confd/tests/compiled_templates/ttl_security/peer_selector/bird6_ipam.cfg +++ b/confd/tests/compiled_templates/ttl_security/peer_selector/bird6_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/compiled_templates/ttl_security/peer_selector/bird_ipam.cfg b/confd/tests/compiled_templates/ttl_security/peer_selector/bird_ipam.cfg index 7b67c8f3c72..284fa44f216 100644 --- a/confd/tests/compiled_templates/ttl_security/peer_selector/bird_ipam.cfg +++ b/confd/tests/compiled_templates/ttl_security/peer_selector/bird_ipam.cfg @@ -14,6 +14,15 @@ function reject_tunnel_routes () { } } +function reject_local_routes () { + # Don't export local routes learned via BPF as they should never leave the node. + if (defined(ifname)) then { + if (ifname ~ "bpf*.cali") then { + reject; + } + } +} + function calico_export_to_bgp_peers(bool internal_peer) { # filter code terminates when it calls `accept;` or `reject;`, # call reject_disabled_pools() first, then reject_tunnel_routes(), @@ -22,6 +31,7 @@ function calico_export_to_bgp_peers(bool internal_peer) { if (internal_peer) then { reject_tunnel_routes(); } + reject_local_routes(); apply_communities(); calico_aggr(); diff --git a/confd/tests/mock_data/calicoctl/mesh/static-routes/input.yaml b/confd/tests/mock_data/calicoctl/mesh/static-routes/input.yaml index 1b83e1dfe9e..a738618a419 100644 --- a/confd/tests/mock_data/calicoctl/mesh/static-routes/input.yaml +++ b/confd/tests/mock_data/calicoctl/mesh/static-routes/input.yaml @@ -5,9 +5,11 @@ metadata: spec: serviceClusterIPs: - cidr: 10.101.0.0/16 + - {} - cidr: fd00:96::/112 serviceLoadBalancerIPs: - cidr: 80.15.0.0/24 + - {} --- diff --git a/e2e/Makefile b/e2e/Makefile index 74194f19331..d34b9b1174e 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -3,10 +3,14 @@ include ../metadata.mk PACKAGE_NAME=github.com/projectcalico/calico/e2e include ../lib.Makefile -build: bin/e2e.test -bin/e2e.test: $(SRC_FILES) +build: bin/k8s/e2e.test bin/adminpolicy/e2e.test +bin/k8s/e2e.test: $(SRC_FILES) mkdir -p bin - $(DOCKER_RUN) $(CALICO_BUILD) go test ./cmd -c -o $@ + $(DOCKER_RUN) $(CALICO_BUILD) go test ./cmd/k8s -c -o $@ + +bin/adminpolicy/e2e.test: $(SRC_FILES) + mkdir -p bin + $(DOCKER_RUN) $(CALICO_BUILD) go test ./cmd/adminpolicy -c -o $@ clean: rm -rf bin/ diff --git a/e2e/cmd/adminpolicy/e2e_test.go b/e2e/cmd/adminpolicy/e2e_test.go new file mode 100644 index 00000000000..d5c67dbe709 --- /dev/null +++ b/e2e/cmd/adminpolicy/e2e_test.go @@ -0,0 +1,74 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "testing" + + "k8s.io/client-go/kubernetes" + _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/config" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/tests" + "sigs.k8s.io/network-policy-api/conformance/utils/flags" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func TestConformance(t *testing.T) { + cfg, err := config.GetConfig() + if err != nil { + t.Fatalf("Error loading Kubernetes config: %v", err) + } + c, err := client.New(cfg, client.Options{}) + if err != nil { + t.Fatalf("Error initializing Kubernetes client: %v", err) + } + + kubeConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(clientcmd.NewDefaultClientConfigLoadingRules(), &clientcmd.ConfigOverrides{}).ClientConfig() + if err != nil { + t.Fatalf("error building Kube config for client-go: %v", err) + } + clientset, err := kubernetes.NewForConfig(kubeConfig) + if err != nil { + t.Fatalf("error when creating Kubernetes ClientSet: %v", err) + } + + v1alpha1.Install(c.Scheme()) + + supportedFeatures := suite.ParseSupportedFeatures(*flags.SupportedFeatures) + exemptFeatures := suite.ParseSupportedFeatures(*flags.ExemptFeatures) + + t.Logf("Running conformance tests with cleanup: %t\n debug: %t\n enable all features: %t \n supported features: [%v]\n exempt features: [%v]", + *flags.CleanupBaseResources, *flags.ShowDebug, *flags.EnableAllSupportedFeatures, *flags.SupportedFeatures, *flags.ExemptFeatures) + + cSuite := suite.New(suite.Options{ + Client: c, + ClientSet: clientset, + KubeConfig: *cfg, + Debug: *flags.ShowDebug, + CleanupBaseResources: *flags.CleanupBaseResources, + SupportedFeatures: supportedFeatures, + ExemptFeatures: exemptFeatures, + EnableAllSupportedFeatures: *flags.EnableAllSupportedFeatures, + }) + cSuite.Setup(t) + + cSuite.Run(t, tests.ConformanceTests) +} diff --git a/e2e/cmd/e2e_test.go b/e2e/cmd/k8s/e2e_test.go similarity index 100% rename from e2e/cmd/e2e_test.go rename to e2e/cmd/k8s/e2e_test.go diff --git a/felix/.semaphore/cleanup.yml b/felix/.semaphore/cleanup.yml index ff4ce5217e4..d989b07e110 100644 --- a/felix/.semaphore/cleanup.yml +++ b/felix/.semaphore/cleanup.yml @@ -2,7 +2,7 @@ version: v1.0 name: Felix agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 execution_time_limit: diff --git a/felix/.semaphore/run-tests-on-vms b/felix/.semaphore/run-tests-on-vms index d0866985e45..c3b5feba81e 100755 --- a/felix/.semaphore/run-tests-on-vms +++ b/felix/.semaphore/run-tests-on-vms @@ -57,7 +57,7 @@ for batch in "${batches[@]}"; do pid=$! pids+=( $pid ) else - VM_NAME=$vm_name ./.semaphore/on-test-vm make --directory=calico/${REPO_NAME} fv-bpf GINKGO_FOCUS=BPF-SAFE FV_NUM_BATCHES=8 FV_BATCHES_TO_RUN="$batch" >& "$log_file" & + VM_NAME=$vm_name ./.semaphore/on-test-vm make --directory=calico/${REPO_NAME} fv-bpf FELIX_FV_NFTABLES="$FELIX_FV_NFTABLES" GINKGO_FOCUS=BPF-SAFE FV_NUM_BATCHES=8 FV_BATCHES_TO_RUN="$batch" >& "$log_file" & pid=$! pids+=( $pid ) fi diff --git a/felix/.semaphore/run-win-fv b/felix/.semaphore/run-win-fv index 2453804a55a..46ae6a138d8 100755 --- a/felix/.semaphore/run-win-fv +++ b/felix/.semaphore/run-win-fv @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -ex -FV_DIR="/home/semaphore/calico/process/testing/winfv" -ERROR_CODE=0 +FV_DIR="/home/semaphore/calico/process/testing/winfv-felix" +EXIT_CODE=0 pushd ${FV_DIR} # Prepare local files @@ -50,19 +50,24 @@ if [[ $FV_PROVISIONER == "aws" ]]; then SCP_CMD=$(echo scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${FV_DIR}/${MASTER_CONNECT_KEY}) ${SCP_CMD} -r ubuntu@${MASTER_IP}:/home/ubuntu/report /home/semaphore elif [[ $FV_PROVISIONER == "capz" ]]; then - chmod +x $FV_DIR/capz/create-cluster.sh - chmod +x $FV_DIR/capz/install-calico.sh - chmod +x $FV_DIR/capz/generate-helpers.sh export KUBE_VERSION="$K8S_VERSION" - /bin/bash -x ./setup-fv-capz.sh -q | tee fv.log - if [[ ${PIPESTATUS[0]} != 0 ]]; then - ERROR_CODE=${PIPESTATUS[0]} + /bin/bash -x ./setup-fv-capz.sh -q | tee setup-fv.log; pstat=${PIPESTATUS[0]} + if [[ $pstat != 0 ]]; then + EXIT_CODE=$pstat fi + mv ./report /home/semaphore + mv ./setup-fv.log /home/semaphore/report + popd fi -ls -ltr ./report -mkdir /home/semaphore/fv.log -# check if *.log glob contains any files so that mv doesn't fail -compgen -G /home/semaphore/report/*.log > /dev/null && mv /home/semaphore/report/*.log /home/semaphore/fv.log +ls -ltr /home/semaphore/report + +# Print relevant snippets from logs +log_regexps='(? /dev/null && \ +for log_file in /home/semaphore/report/*.log; do + prefix="[$(basename ${log_file})]" + cat ${log_file} | iconv -f UTF-16 -t UTF-8 | sed 's/\r$//g' | grep --line-buffered --perl ${log_regexps} -B 2 -A 15 | sed 's/.*/'"${prefix}"' &/g' +done; # Stop for debug echo "Check for pause file..." @@ -72,19 +77,11 @@ do sleep 30 done -# Print relevant snippets from logs -log_regexps='(? /dev/null && \ -for log_file in /home/semaphore/fv.log/*.log; do - prefix="[$(basename ${log_file})]" - cat ${log_file} | iconv -f UTF-16 -t UTF-8 | sed 's/\r$//g' | grep --line-buffered --perl ${log_regexps} -B 2 -A 15 | sed 's/.*/'"${prefix}"' &/g' -done; - # Search for error code file -if [[ -f /home/semaphore/report/error-codes || $ERROR_CODE != 0 ]]; +if [[ -f /home/semaphore/report/error-codes || $EXIT_CODE != 0 ]]; then echo "Windows FV returned error(s)." exit 1 fi -echo "Run Windows FV is done." \ No newline at end of file +echo "Run Windows FV is done." diff --git a/felix/.semaphore/semaphore.yml b/felix/.semaphore/semaphore.yml index 1097dd08d2c..32c5b80e58e 100644 --- a/felix/.semaphore/semaphore.yml +++ b/felix/.semaphore/semaphore.yml @@ -6,7 +6,7 @@ execution_time_limit: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 auto_cancel: @@ -34,8 +34,6 @@ global_job_config: - name: docker-hub prologue: commands: - # make some room on the disk - - sudo rm -rf ~/.kiex ~/.phpbrew ~/.rbenv ~/.nvm ~/.kerl - echo $DOCKERHUB_PASSWORD | docker login --username "$DOCKERHUB_USERNAME" --password-stdin blocks: @@ -44,7 +42,7 @@ blocks: task: agent: machine: - type: e1-standard-4 + type: f1-standard-2 os_image: ubuntu2004 jobs: - name: Build and run UT, k8sfv @@ -106,7 +104,7 @@ blocks: - artifact push job ${REPORT_DIR} --destination semaphore/test-results --expire-in ${SEMAPHORE_ARTIFACT_EXPIRY} || true - artifact push job ${LOGS_DIR} --destination semaphore/logs --expire-in ${SEMAPHORE_ARTIFACT_EXPIRY} || true - aws ec2 delete-key-pair --key-name ${KEYPAIR_NAME} || true - - cd ~/calico/process/testing/winfv && NAME_PREFIX="${CLUSTER_NAME}" /bin/bash -x ./setup-fv.sh -q -u + - cd ~/calico/process/testing/winfv-felix && NAME_PREFIX="${CLUSTER_NAME}" /bin/bash -x ./setup-fv.sh -q -u env_vars: - name: SEMAPHORE_ARTIFACT_EXPIRY value: 2w @@ -144,8 +142,6 @@ blocks: - sudo systemctl stop docker - sudo umount /var/lib/docker && sudo killall qemu-nbd || true - sudo systemctl start docker - # Free up space on the build machine. - - sudo rm -rf ~/.kiex ~/.phpbrew ~/.rbenv ~/.nvm ~/.kerl - checkout - cache restore go-pkg-cache - cache restore go-mod-cache @@ -206,13 +202,13 @@ blocks: - ./.semaphore/clean-up-vms ${VM_PREFIX} secrets: - name: google-service-account-for-gce -- name: Static checks on e1-standard-8 +- name: Static checks on f1-standard-4 dependencies: [] task: agent: machine: # Linters use a lot of RAM so use a bigger machine type. - type: e1-standard-8 + type: f1-standard-4 os_image: ubuntu2004 prologue: commands: diff --git a/felix/.semaphore/update_pins.yml b/felix/.semaphore/update_pins.yml index 7304863ff5e..69ef14ee02a 100644 --- a/felix/.semaphore/update_pins.yml +++ b/felix/.semaphore/update_pins.yml @@ -6,7 +6,7 @@ execution_time_limit: agent: machine: - type: e1-standard-2 + type: f1-standard-2 os_image: ubuntu2004 global_job_config: diff --git a/felix/Makefile b/felix/Makefile index 22e5937d71e..9ec271a0d2d 100644 --- a/felix/Makefile +++ b/felix/Makefile @@ -42,7 +42,7 @@ BPFGPL_CONTAINER_PATH=/go/src/github.com/projectcalico/calico/felix/bpf-gpl # List of Go files that are generated by the build process. Builds should # depend on these, clean removes them. -GENERATED_FILES=proto/felixbackend.pb.go bpf/asm/opcode_string.go +GENERATED_FILES=proto/felixbackend.pb.go bpf/asm/opcode_string.go routetable/routeclass_string.go # All Felix go files. SRC_FILES:=$(shell find . $(foreach dir,$(NON_FELIX_DIRS) fv,-path ./$(dir) -prune -o) -type f -name '*.go' -print) $(GENERATED_FILES) @@ -184,14 +184,19 @@ bin/calico-felix-race-$(ARCH): $(LIBBPF_A) $(SRC_FILES) ../go.mod fi # Generate the protobuf bindings for go. The proto/felixbackend.pb.go file is included in SRC_FILES +SKIP_PROTOBUF ?= false protobuf proto/felixbackend.pb.go: proto/felixbackend.proto - docker run --rm --user $(LOCAL_USER_ID):$(LOCAL_GROUP_ID) \ + if [ $(SKIP_PROTOBUF) = "true" ]; then \ + echo "Skipping build of protobufs."; \ + else \ + docker run --rm --user $(LOCAL_USER_ID):$(LOCAL_GROUP_ID) \ -v $(CURDIR):/code -v $(CURDIR)/proto:/src:rw \ $(PROTOC_CONTAINER) \ --gogofaster_out=plugins=grpc:. \ - felixbackend.proto - # Make sure the generated code won't cause a static-checks failure. - $(MAKE) fix + felixbackend.proto && \ + # Make sure the generated code won't cause a static-checks failure. \ + $(MAKE) fix; \ + fi # We pre-build lots of different variants of the TC programs, defer to the script. BPF_GPL_O_FILES:=$(addprefix bpf-gpl/,$(shell bpf-gpl/list-objs)) @@ -228,6 +233,9 @@ clean-bpf: bpf/asm/opcode_string.go: bpf/asm/asm.go $(DOCKER_GO_BUILD) go generate ./bpf/asm/ +routetable/routeclass_string.go: routetable/defs.go + $(DOCKER_GO_BUILD) go generate ./routetable/ + ############################################################################### # Building the image ############################################################################### @@ -463,7 +471,7 @@ st: ############################################################################### # Generate files ############################################################################### -gen-files: protobuf bpf/asm/opcode_string.go +gen-files: $(GENERATED_FILES) ############################################################################### # CI/CD diff --git a/felix/aws/ec2_test.go b/felix/aws/ec2_test.go index 5b6d585bcf6..113c5c219cb 100644 --- a/felix/aws/ec2_test.go +++ b/felix/aws/ec2_test.go @@ -162,7 +162,7 @@ var _ = Describe("AWS Tests", func() { Expect(errMsg).To(Equal(fmt.Sprintf("%s: %s", fakeCode, fakeMsg))) fakeMsg = "fake non-aws error" - err := fmt.Errorf(fakeMsg) + err := fmt.Errorf("%s", fakeMsg) errMsg = convertError(err) Expect(errMsg).To(Equal(fakeMsg)) }) @@ -181,7 +181,7 @@ var _ = Describe("AWS Tests", func() { Expect(retriable(awsErr)).To(BeFalse()) fakeMsg = "non-aws error" - err := fmt.Errorf(fakeMsg) + err := fmt.Errorf("%s", fakeMsg) Expect(retriable(err)).To(BeFalse()) }) diff --git a/felix/bpf-gpl/bpf.h b/felix/bpf-gpl/bpf.h index 85245d5f992..5b684e384fd 100644 --- a/felix/bpf-gpl/bpf.h +++ b/felix/bpf-gpl/bpf.h @@ -66,8 +66,8 @@ #define CALI_F_HEP ((CALI_COMPILE_FLAGS) & (CALI_TC_HOST_EP | CALI_TC_NAT_IF)) #define CALI_F_WEP (!CALI_F_HEP) -#define CALI_F_TUNNEL ((CALI_COMPILE_FLAGS) & CALI_TC_TUNNEL) -#define CALI_F_L3_DEV ((CALI_COMPILE_FLAGS) & CALI_TC_L3_DEV) +#define CALI_F_TUNNEL (((CALI_COMPILE_FLAGS) & CALI_TC_TUNNEL) != 0) +#define CALI_F_L3_DEV (((CALI_COMPILE_FLAGS) & CALI_TC_L3_DEV) != 0) #define CALI_F_NAT_IF (((CALI_COMPILE_FLAGS) & CALI_TC_NAT_IF) != 0) #define CALI_F_LO (((CALI_COMPILE_FLAGS) & CALI_TC_LO) != 0) diff --git a/felix/bpf-gpl/conntrack.h b/felix/bpf-gpl/conntrack.h index 2cfd25f0cea..8df6fd00fde 100644 --- a/felix/bpf-gpl/conntrack.h +++ b/felix/bpf-gpl/conntrack.h @@ -985,14 +985,27 @@ static CALI_BPF_INLINE struct calico_ct_result calico_ct_lookup(struct cali_tc_c CALI_CT_DEBUG("CT RPF failed ifindex %d != %d\n", src_to_dst->ifindex, ifindex); } - /* Do not worry about packets returning from the same direction as - * the outgoing packets. - * - * Do not check if packets are returning from the NP vxlan tunnel. - */ - if (!same_if && !ret_from_tun && !hep_rpf_check(ctx) && !CALI_F_NAT_IF && !CALI_F_LO) { + + bool rpf_passed = false; + if (same_if || ret_from_tun || CALI_F_NAT_IF || CALI_F_LO) { + /* Do not worry about packets returning from the same direction as + * the outgoing packets. + * + * Do not check if packets are returning from the NP vxlan tunnel. + */ + rpf_passed = true; + } else if (CALI_F_HEP) { + rpf_passed = hep_rpf_check(ctx); + } else { + rpf_passed = wep_rpf_check(ctx, cali_rt_lookup(&ctx->state->ip_src)); + } + if (!rpf_passed) { ct_result_set_flag(result.rc, CT_RES_RPF_FAILED); + src_to_dst->ifindex = CT_INVALID_IFINDEX; + CALI_CT_DEBUG("CT RPF failed invalidating ifindex"); } else { + CALI_CT_DEBUG("Updating ifindex from %d to %d\n", + src_to_dst->ifindex, ifindex); src_to_dst->ifindex = ifindex; } } else if (src_to_dst->ifindex != CT_INVALID_IFINDEX) { @@ -1007,7 +1020,7 @@ static CALI_BPF_INLINE struct calico_ct_result calico_ct_lookup(struct cali_tc_c if (CALI_F_TO_HOST) { /* Fill in the ifindex we recorded in the opposite direction. The caller - * may use it directly forward the packet to the same interface where + * may use it to directly forward the packet to the same interface where * packets in the opposite direction are coming from. */ result.ifindex_fwd = dst_to_src->ifindex; diff --git a/felix/bpf-gpl/fib.h b/felix/bpf-gpl/fib.h index 72677c40322..fd2830e9d4d 100644 --- a/felix/bpf-gpl/fib.h +++ b/felix/bpf-gpl/fib.h @@ -137,6 +137,19 @@ static CALI_BPF_INLINE int forward_or_drop(struct cali_tc_ctx *ctx) CALI_DEBUG("Redirect directly to interface (%d) failed.\n", iface); /* fall through to FIB if enabled or the IP stack, don't give up yet. */ rc = TC_ACT_UNSPEC; +#ifdef BPF_CORE_SUPPORTED + } else if (CALI_F_FROM_HEP && bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_redirect_peer)) { + bool redirect_peer = GLOBAL_FLAGS & CALI_GLOBALS_REDIRECT_PEER; + + if (redirect_peer && ct_result_rc(state->ct_result.rc) == CALI_CT_ESTABLISHED_BYPASS && + state->ct_result.ifindex_fwd != CT_INVALID_IFINDEX) { + rc = bpf_redirect_peer(state->ct_result.ifindex_fwd, 0); + if (rc == TC_ACT_REDIRECT) { + CALI_DEBUG("Redirect to peer interface (%d) succeeded.\n", state->ct_result.ifindex_fwd); + goto skip_fib; + } + } +#endif } #if CALI_FIB_ENABLED diff --git a/felix/bpf-gpl/globals.h b/felix/bpf-gpl/globals.h index fc7b614f640..3d821e04d3f 100644 --- a/felix/bpf-gpl/globals.h +++ b/felix/bpf-gpl/globals.h @@ -52,6 +52,8 @@ enum cali_globals_flags { CALI_GLOBALS_RESERVED7 = 0x00000040, CALI_GLOBALS_NO_DSR_CIDRS = 0x00000080, CALI_GLOBALS_LO_UDP_ONLY = 0x00000100, + CALI_GLOBALS_RESERVED10 = 0x00000200, + CALI_GLOBALS_REDIRECT_PEER = 0x00000400, }; struct cali_ctlb_globals { diff --git a/felix/bpf-gpl/tc.c b/felix/bpf-gpl/tc.c index 50e84680fca..5c0a073e657 100644 --- a/felix/bpf-gpl/tc.c +++ b/felix/bpf-gpl/tc.c @@ -308,14 +308,7 @@ static CALI_BPF_INLINE void calico_tc_process_ct_lookup(struct cali_tc_ctx *ctx) } if (ct_result_rpf_failed(ctx->state->ct_result.rc)) { - if (!CALI_F_FROM_WEP) { - /* We are possibly past (D)NAT, but that is ok, we need to let the - * IP stack do the RPF check on the source, dest is not important. - */ - goto deny; - } else if (!wep_rpf_check(ctx, cali_rt_lookup(&ctx->state->ip_src))) { - goto deny; - } + goto deny; } if (ct_result_rc(ctx->state->ct_result.rc) == CALI_CT_MID_FLOW_MISS) { @@ -1319,12 +1312,22 @@ int calico_tc_skb_new_flow_entrypoint(struct __sk_buff *skb) if (CALI_F_TO_HOST && state->flags & CALI_ST_SKIP_FIB) { ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; } - /* Packets received at WEP with CALI_CT_FLAG_SKIP_FIB mark signal - * that all traffic on this connection must flow via host namespace as it was - * originally meant for host, but got redirected to a WEP by a 3rd party DNAT rule. - */ - if (CALI_F_TO_WEP && ((ctx->skb->mark & CALI_SKB_MARK_SKIP_FIB) == CALI_SKB_MARK_SKIP_FIB)) { - ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; + if (CALI_F_TO_WEP) { + if (!(ctx->skb->mark & CALI_SKB_MARK_SEEN)) { + /* If the packet wasn't seen, must come from host. There is no + * need to do FIB lookup for returning traffic. In fact, it may + * not be always correct, e.g. when some mesh and custom iptables + * rules are used by the host. So don't mess with it. + */ + ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; + } else if ((ctx->skb->mark & CALI_SKB_MARK_SKIP_FIB) == CALI_SKB_MARK_SKIP_FIB) { + /* Packets received at WEP with CALI_CT_FLAG_SKIP_FIB mark signal + * that all traffic on this connection must flow via host + * namespace as it was originally meant for host, but got + * redirected to a WEP by a 3rd party DNAT rule. + */ + ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; + } } if (CALI_F_TO_HOST && CALI_F_NAT_IF) { ct_ctx_nat->flags |= CALI_CT_FLAG_VIA_NAT_IF; diff --git a/felix/bpf/conntrack/cleanup.go b/felix/bpf/conntrack/cleanup.go index 34896b37104..c70304e0647 100644 --- a/felix/bpf/conntrack/cleanup.go +++ b/felix/bpf/conntrack/cleanup.go @@ -107,15 +107,23 @@ func (l *LivenessScanner) Check(ctKey KeyInterface, ctVal ValueInterface, get En // entry does not exist now, we are not racing with the BPF code, we must have // removed the entry or there is some external inconsistency. In either case, the // FWD entry should be removed. - log.Debug("Found a forward NAT conntrack entry with no reverse entry, removing...") + if debug { + log.WithField("k", ctKey).Debug("Deleting forward NAT conntrack entry with no reverse entry.") + } return ScanVerdictDelete } else if err != nil { - log.WithError(err).Warn("Failed to look up conntrack entry.") + log.WithFields(log.Fields{ + "fwdKey": ctKey, + "revKey": ctVal.ReverseNATKey(), + }).WithError(err).Warn("Failed to look up reverse conntrack entry.") return ScanVerdictOK } if reason, expired := l.timeouts.EntryExpired(now, ctKey.Proto(), revEntry); expired { if debug { - log.WithField("reason", reason).Debug("Deleting expired conntrack forward-NAT entry") + log.WithFields(log.Fields{ + "reason": reason, + "key": ctKey, + }).Debug("Deleting expired conntrack forward-NAT entry") } return ScanVerdictDelete // do not delete the reverse entry yet to avoid breaking the iterating @@ -125,19 +133,28 @@ func (l *LivenessScanner) Check(ctKey KeyInterface, ctVal ValueInterface, get En case TypeNATReverse: if reason, expired := l.timeouts.EntryExpired(now, ctKey.Proto(), ctVal); expired { if debug { - log.WithField("reason", reason).Debug("Deleting expired conntrack reverse-NAT entry") + log.WithFields(log.Fields{ + "reason": reason, + "key": ctKey, + }).Debug("Deleting expired conntrack reverse-NAT entry") } return ScanVerdictDelete } case TypeNormal: if reason, expired := l.timeouts.EntryExpired(now, ctKey.Proto(), ctVal); expired { if debug { - log.WithField("reason", reason).Debug("Deleting expired normal conntrack entry") + log.WithFields(log.Fields{ + "reason": reason, + "key": ctKey, + }).Debug("Deleting expired normal conntrack entry") } return ScanVerdictDelete } default: - log.WithField("type", ctVal.Type()).Warn("Unknown conntrack entry type!") + log.WithFields(log.Fields{ + "type": ctVal.Type(), + "key": ctKey, + }).Warn("Unknown conntrack entry type!") } return ScanVerdictOK diff --git a/felix/bpf/conntrack/conntrack_suite_test.go b/felix/bpf/conntrack/conntrack_suite_test.go index af2ab992149..3b7aaaf24d2 100644 --- a/felix/bpf/conntrack/conntrack_suite_test.go +++ b/felix/bpf/conntrack/conntrack_suite_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,20 +17,15 @@ package conntrack_test import ( "testing" + . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" - "github.com/sirupsen/logrus" + . "github.com/onsi/gomega" - "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/testutils" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" ) func init() { testutils.HookLogrusForGinkgo() - logrus.AddHook(&logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) } func TestBPFConntrack(t *testing.T) { diff --git a/felix/bpf/ipsets/map.go b/felix/bpf/ipsets/map.go index d57496a2049..f0443899b0a 100644 --- a/felix/bpf/ipsets/map.go +++ b/felix/bpf/ipsets/map.go @@ -16,6 +16,7 @@ package ipsets import ( "encoding/binary" + "fmt" "net" "strconv" "strings" @@ -95,6 +96,10 @@ func (e IPSetEntry) Port() uint16 { return binary.LittleEndian.Uint16(e[16:18]) } +func (e IPSetEntry) String() string { + return fmt.Sprintf("0x%08x %11s prefix %d port %d proto %d", e.SetID(), e.Addr(), e.PrefixLen(), e.Port(), e.Protocol()) +} + func IPSetEntryFromBytes(b []byte) IPSetEntryInterface { var e IPSetEntry copy(e[:], b) @@ -153,3 +158,26 @@ func ProtoIPSetMemberToBPFEntry(id uint64, member string) IPSetEntryInterface { entry := MakeBPFIPSetEntry(id, cidr, port, protocol) return entry } + +type MapMem map[IPSetEntry]struct{} + +func MapMemIter(m MapMem) func(k, v []byte) { + ks := len(IPSetEntry{}) + + return func(k, v []byte) { + var key IPSetEntry + copy(key[:ks], k[:ks]) + + m[key] = struct{}{} + } +} + +func (m MapMem) String() string { + var out string + + for k := range m { + out += k.String() + "\n" + } + + return out +} diff --git a/felix/bpf/ipsets/map6.go b/felix/bpf/ipsets/map6.go index 0d16247bb39..75b6987c92d 100644 --- a/felix/bpf/ipsets/map6.go +++ b/felix/bpf/ipsets/map6.go @@ -16,6 +16,7 @@ package ipsets import ( "encoding/binary" + "fmt" "net" "strconv" "strings" @@ -81,6 +82,10 @@ func (e IPSetEntryV6) Port() uint16 { return binary.LittleEndian.Uint16(e[28:30]) } +func (e IPSetEntryV6) String() string { + return fmt.Sprintf("0x%08x %20s prefix %d port %d proto %d", e.SetID(), e.Addr(), e.PrefixLen(), e.Port(), e.Protocol()) +} + func IPSetEntryV6FromBytes(b []byte) IPSetEntryInterface { var e IPSetEntryV6 copy(e[:], b) @@ -138,3 +143,26 @@ func ProtoIPSetMemberToBPFEntryV6(id uint64, member string) IPSetEntryInterface entry := MakeBPFIPSetEntryV6(id, cidr, port, protocol) return entry } + +type MapMemV6 map[IPSetEntryV6]struct{} + +func MapMemV6Iter(m MapMemV6) func(k, v []byte) { + ks := len(IPSetEntryV6{}) + + return func(k, v []byte) { + var key IPSetEntryV6 + copy(key[:ks], k[:ks]) + + m[key] = struct{}{} + } +} + +func (m MapMemV6) String() string { + var out string + + for k := range m { + out += k.String() + "\n" + } + + return out +} diff --git a/felix/bpf/libbpf/libbpf.go b/felix/bpf/libbpf/libbpf.go index 82b4d0b16b0..90c12f18ea7 100644 --- a/felix/bpf/libbpf/libbpf.go +++ b/felix/bpf/libbpf/libbpf.go @@ -167,7 +167,7 @@ func DetachClassifier(ifindex, handle, pref int, ingress bool) error { } // AttachClassifier return the program id and pref and handle of the qdisc -func (o *Obj) AttachClassifier(secName, ifName string, ingress bool) (int, int, int, error) { +func (o *Obj) AttachClassifier(secName, ifName string, ingress bool, prio int) (int, int, int, error) { cSecName := C.CString(secName) cIfName := C.CString(ifName) defer C.free(unsafe.Pointer(cSecName)) @@ -177,7 +177,7 @@ func (o *Obj) AttachClassifier(secName, ifName string, ingress bool) (int, int, return -1, -1, -1, err } - ret, err := C.bpf_tc_program_attach(o.obj, cSecName, C.int(ifIndex), C.bool(ingress)) + ret, err := C.bpf_tc_program_attach(o.obj, cSecName, C.int(ifIndex), C.bool(ingress), C.int(prio)) if err != nil { return -1, -1, -1, fmt.Errorf("error attaching tc program %w", err) } @@ -381,6 +381,7 @@ const ( GlobalsRPFOptionStrict uint32 = C.CALI_GLOBALS_RPF_OPTION_STRICT GlobalsNoDSRCidrs uint32 = C.CALI_GLOBALS_NO_DSR_CIDRS GlobalsLoUDPOnly uint32 = C.CALI_GLOBALS_LO_UDP_ONLY + GlobalsRedirectPeer uint32 = C.CALI_GLOBALS_REDIRECT_PEER ) func TcSetGlobals( diff --git a/felix/bpf/libbpf/libbpf_api.h b/felix/bpf/libbpf/libbpf_api.h index 649e7aa518b..5a8cbf2b6d6 100644 --- a/felix/bpf/libbpf/libbpf_api.h +++ b/felix/bpf/libbpf/libbpf_api.h @@ -50,12 +50,12 @@ int bpf_program_fd(struct bpf_object *obj, char *secname) return fd; } -struct bpf_tc_opts bpf_tc_program_attach(struct bpf_object *obj, char *secName, int ifIndex, bool ingress) +struct bpf_tc_opts bpf_tc_program_attach(struct bpf_object *obj, char *secName, int ifIndex, bool ingress, int prio) { DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .attach_point = ingress ? BPF_TC_INGRESS : BPF_TC_EGRESS, ); - DECLARE_LIBBPF_OPTS(bpf_tc_opts, attach); + DECLARE_LIBBPF_OPTS(bpf_tc_opts, attach, .priority=prio,); attach.prog_fd = bpf_program__fd(bpf_object__find_program_by_name(obj, secName)); if (attach.prog_fd < 0) { diff --git a/felix/bpf/libbpf/libbpf_stub.go b/felix/bpf/libbpf/libbpf_stub.go index e78cef89132..ac784bb3b86 100644 --- a/felix/bpf/libbpf/libbpf_stub.go +++ b/felix/bpf/libbpf/libbpf_stub.go @@ -74,7 +74,7 @@ func DetachClassifier(ifindex, handle, pref int, ingress bool) error { panic("LIBBPF syscall stub") } -func (o *Obj) AttachClassifier(secName, ifName string, ingress bool) (int, int, int, error) { +func (o *Obj) AttachClassifier(secName, ifName string, ingress bool, prio int) (int, int, int, error) { panic("LIBBPF syscall stub") } @@ -136,6 +136,7 @@ const ( GlobalsRPFOptionStrict uint32 = 32 GlobalsNoDSRCidrs uint32 = 12345 GlobalsLoUDPOnly uint32 = 12345 + GlobalsRedirectPeer uint32 = 12345 ) func TcSetGlobals(_ *Map, globalData *TcGlobalData) error { diff --git a/felix/bpf/maps/maps.go b/felix/bpf/maps/maps.go index 877fbb9a924..47033910c89 100644 --- a/felix/bpf/maps/maps.go +++ b/felix/bpf/maps/maps.go @@ -576,6 +576,7 @@ func (b *PinnedMap) Open() error { } func (b *PinnedMap) repinAt(fd int, from, to string) error { + log.Infof("Repinning BPF map from %s to %s", from, to) err := libbpf.ObjPin(fd, to) if err != nil { return fmt.Errorf("error repinning %s to %s: %w", from, to, err) @@ -604,19 +605,27 @@ func (b *PinnedMap) EnsureExists() error { return nil } - // In case felix restarts in the middle of migration, we might end up with - // old map. Repin the old map and let the map creation continue. + // In case felix restarts in the middle of migration, the in-use map + // will be pinned with suffix "_old" and the map in the normal place + // wil be a partially-migrated map. Clean up the partial map and move + // the old map back into its normal place. if b.oldMapExists() { - log.WithField("name", b.Name).Debug("Old map exists") + log.WithField("name", b.Name).Info("Old map exists (from previous migration attempt?)") if _, err := os.Stat(b.Path()); err == nil { - os.Remove(b.Path()) + err := os.Remove(b.Path()) + if err != nil { + log.WithError(err).Warning("Failed to remove partially-migrated map. Ignoring...") + } } fd, err := libbpf.ObjGet(oldMapPath) if err != nil { return fmt.Errorf("cannot get old map at %s: %w", oldMapPath, err) } err = b.repinAt(fd, oldMapPath, b.Path()) - syscall.Close(fd) + closeErr := syscall.Close(fd) + if closeErr != nil { + log.WithError(err).Warn("Error from fd.Close(). Ignoring.") + } if err != nil { return fmt.Errorf("error repinning old map %s to %s, err=%w", oldMapPath, b.Path(), err) } @@ -641,9 +650,10 @@ func (b *PinnedMap) EnsureExists() error { }).Warn("Map with same name but different parameters exists. Deleting it") } else { if b.MaxEntries == mapInfo.MaxEntries { + log.WithField("name", b.Name).Info("Map already exists with correct parameters.") return nil } - log.WithField("name", b.Name).Debugf("Size changed %d -> %d", mapInfo.MaxEntries, b.MaxEntries) + log.WithField("name", b.Name).Infof("BPF map size changed; need to migrate %d -> %d", mapInfo.MaxEntries, b.MaxEntries) // store the old fd b.oldfd = b.MapFD() @@ -651,13 +661,16 @@ func (b *PinnedMap) EnsureExists() error { err = b.repinAt(int(b.MapFD()), b.Path(), oldMapPath) if err != nil { - return fmt.Errorf("error migrating the old map %w", err) + return fmt.Errorf("error repinning the old map %w", err) } copyData = true // Do not close the oldfd if the map is updated by the BPF programs. if !b.UpdatedByBPF { defer func() { - b.oldfd.Close() + err := b.oldfd.Close() + if err != nil { + log.WithError(err).Warn("Error closing old map fd. Ignoring.") + } b.oldfd = 0 }() } @@ -690,10 +703,13 @@ func (b *PinnedMap) EnsureExists() error { // same version but of different size. err := b.copyFromOldMap() if err != nil { - b.fd.Close() + log.WithError(err).Error("error copying data from old map") + closeErr := b.fd.Close() + if closeErr != nil { + log.WithError(closeErr).Warn("Error when closing FD, ignoring...") + } b.fd = 0 b.fdLoaded = false - log.WithError(err).Error("error copying data from old map") return err } // Delete the old pin if the map is not updated by BPF programs. @@ -707,7 +723,10 @@ func (b *PinnedMap) EnsureExists() error { // Handle map upgrade. err = b.upgrade() if err != nil { - b.fd.Close() + closeErr := b.fd.Close() + if closeErr != nil { + log.WithError(closeErr).Warn("Error when closing FD, ignoring...") + } b.fd = 0 b.fdLoaded = false return err diff --git a/felix/bpf/polprog/pol_prog_builder.go b/felix/bpf/polprog/pol_prog_builder.go index f3acbba5bd6..2782abadb73 100644 --- a/felix/bpf/polprog/pol_prog_builder.go +++ b/felix/bpf/polprog/pol_prog_builder.go @@ -527,6 +527,10 @@ func (p *Builder) writePolicyRules(policy Policy, actionLabels map[string]string for ruleIdx, rule := range policy.Rules { log.Debugf("Start of rule %d", ruleIdx) p.b.AddCommentF("Start of rule %s", rule) + ipsets := p.printIPSetIDs(rule) + if ipsets != "" { + p.b.AddCommentF("IPSets %s", p.printIPSetIDs(rule)) + } p.b.AddCommentF("Rule MatchID: %d", rule.MatchID) action := strings.ToLower(rule.Action) if action == "log" { @@ -893,6 +897,37 @@ func (p *Builder) writeCIDRSMatch(negate bool, leg matchLeg, cidrs []string) { } } +func (p *Builder) printIPSetIDs(r Rule) string { + str := "" + joinIDs := func(ipSets []string) string { + idString := []string{} + for _, ipSetID := range ipSets { + id := p.ipSetIDProvider.GetNoAlloc(ipSetID) + if id != 0 { + idString = append(idString, fmt.Sprintf("0x%x", id)) + } + } + return strings.Join(idString[:], ",") + } + srcIDString := joinIDs(r.SrcIpSetIds) + if srcIDString != "" { + str = str + fmt.Sprintf("src_ip_set_ids:<%s> ", srcIDString) + } + notSrcIDString := joinIDs(r.NotSrcIpSetIds) + if notSrcIDString != "" { + str = str + fmt.Sprintf("not_src_ip_set_ids:<%s> ", notSrcIDString) + } + dstIDString := joinIDs(r.DstIpSetIds) + if dstIDString != "" { + str = str + fmt.Sprintf("dst_ip_set_ids:<%s> ", dstIDString) + } + notDstIDString := joinIDs(r.NotDstIpSetIds) + if notDstIDString != "" { + str = str + fmt.Sprintf("not_dst_ip_set_ids:<%s> ", notDstIDString) + } + return str +} + func (p *Builder) writeIPSetMatch(negate bool, leg matchLeg, ipSets []string) { // IP sets are different to CIDRs, if we have multiple IP sets then they all have to match // so we treat them as independent match criteria. @@ -1211,12 +1246,6 @@ func WithAllowDenyJumps(allow, deny int) Option { } } -func WithIPv6() Option { - return func(p *Builder) { - p.forIPv6 = true - } -} - // WithPolicyMapIndexAndStride tells the builder the "shape" of the policy // jump map, allowing it to split the program if it gets too large. // entryPointIdx is the jump map key for the first "entry point" program. @@ -1230,6 +1259,12 @@ func WithPolicyMapIndexAndStride(entryPointIdx, stride int) Option { } } +func WithIPv6() Option { + return func(p *Builder) { + p.forIPv6 = true + } +} + func protocolToName(protocol *proto.Protocol) string { var pcol string switch p := protocol.NumberOrName.(type) { diff --git a/felix/bpf/proxy/endpoint.go b/felix/bpf/proxy/endpoint.go new file mode 100644 index 00000000000..f654b51c2d3 --- /dev/null +++ b/felix/bpf/proxy/endpoint.go @@ -0,0 +1,152 @@ +// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// NOTICE: +// +// Original code pulled from k8s.io@1.29.4, package: pkg/proxy/endpoints.go. +// Adapted for legacy use in this repository. + +package proxy + +import ( + "net" + "strconv" + + "k8s.io/apimachinery/pkg/util/sets" + k8sp "k8s.io/kubernetes/pkg/proxy" +) + +// endpointInfo contains base information that defines an endpoint. +type endpointInfo struct { + // Cache this values to improve performance + ip string + port int + // endpoint is the same as net.JoinHostPort(ip,port) + endpoint string + + // isLocal indicates whether the endpoint is running on same host as kube-proxy. + isLocal bool + + // ready indicates whether this endpoint is ready and NOT terminating, unless + // PublishNotReadyAddresses is set on the service, in which case it will just + // always be true. + ready bool + // serving indicates whether this endpoint is ready regardless of its terminating state. + // For pods this is true if it has a ready status regardless of its deletion timestamp. + serving bool + // terminating indicates whether this endpoint is terminating. + // For pods this is true if it has a non-nil deletion timestamp. + terminating bool + + // zoneHints represent the zone hints for the endpoint. This is based on + // endpoint.hints.forZones[*].name in the EndpointSlice API. + zoneHints sets.Set[string] +} + +var _ k8sp.Endpoint = &endpointInfo{} + +type EndpoiontInfoOpt func(*endpointInfo) + +// EndpointInfoOptIsLocal applies the given bool to the endpoint's isLocal field. +func EndpointInfoOptIsLocal(b bool) EndpoiontInfoOpt { + return func(ep *endpointInfo) { + ep.isLocal = b + } +} + +// EndpointInfoOptIsReady applies the given bool to the endpoint's ready field. +func EndpointInfoOptIsReady(b bool) EndpoiontInfoOpt { + return func(ep *endpointInfo) { + ep.ready = b + } +} + +// EndpointInfoOptIsServing applies the given bool to the endpoint's serving field. +func EndpointInfoOptIsServing(b bool) EndpoiontInfoOpt { + return func(ep *endpointInfo) { + ep.serving = b + } +} + +// EndpointInfoOptIsTerminating applies the given bool to the endpoint's terminating field. +func EndpointInfoOptIsTerminating(b bool) EndpoiontInfoOpt { + return func(ep *endpointInfo) { + ep.terminating = b + } +} + +// EndpointInfoOptZoneHints applies the given set to the endpoint's zoneHints field. +func EndpointInfoOptZoneHints(b sets.Set[string]) EndpoiontInfoOpt { + return func(ep *endpointInfo) { + ep.zoneHints = b + } +} + +// NewEndpointInfo creates a new endpointInfo, returning it as a k8s proxy Endpoint. +func NewEndpointInfo(ip string, port int, opts ...EndpoiontInfoOpt) k8sp.Endpoint { + ep := &endpointInfo{ + ip: ip, + port: port, + endpoint: net.JoinHostPort(ip, strconv.Itoa(port)), + } + + for _, opt := range opts { + opt(ep) + } + + return ep +} + +// String is part of proxy.Endpoint interface. +func (info *endpointInfo) String() string { + return info.endpoint +} + +// IP returns just the IP part of the endpoint, it's a part of proxy.Endpoint interface. +func (info *endpointInfo) IP() string { + return info.ip +} + +// Port returns just the Port part of the endpoint. +func (info *endpointInfo) Port() int { + return info.port +} + +// IsLocal is part of proxy.Endpoint interface. +func (info *endpointInfo) IsLocal() bool { + return info.isLocal +} + +// IsReady returns true if an endpoint is ready and not terminating. +func (info *endpointInfo) IsReady() bool { + return info.ready +} + +// IsServing returns true if an endpoint is ready, regardless of if the +// endpoint is terminating. +func (info *endpointInfo) IsServing() bool { + return info.serving +} + +// IsTerminating retruns true if an endpoint is terminating. For pods, +// that is any pod with a deletion timestamp. +func (info *endpointInfo) IsTerminating() bool { + return info.terminating +} + +// ZoneHints returns the zone hint for the endpoint. +func (info *endpointInfo) ZoneHints() sets.Set[string] { + return info.zoneHints +} diff --git a/felix/bpf/proxy/lb_src_range_test.go b/felix/bpf/proxy/lb_src_range_test.go index 149b58002eb..a6f01c00d1a 100644 --- a/felix/bpf/proxy/lb_src_range_test.go +++ b/felix/bpf/proxy/lb_src_range_test.go @@ -68,7 +68,7 @@ func testfn(makeIPs func(ips []string) proxy.K8sServicePortOption) { ), }, EpsMap: k8sp.EndpointsMap{ - svcKey: []k8sp.Endpoint{&k8sp.BaseEndpointInfo{Endpoint: "10.1.0.1:5555"}}, + svcKey: []k8sp.Endpoint{proxy.NewEndpointInfo("10.1.0.1", 5555)}, }, } makestep := func(step func()) func() { diff --git a/felix/bpf/proxy/proxy.go b/felix/bpf/proxy/proxy.go index d200df93882..1a2bc643566 100644 --- a/felix/bpf/proxy/proxy.go +++ b/felix/bpf/proxy/proxy.go @@ -83,7 +83,7 @@ type proxy struct { k8s kubernetes.Interface ipFamily int - epsChanges *k8sp.EndpointChangeTracker + epsChanges *k8sp.EndpointsChangeTracker svcChanges *k8sp.ServiceChangeTracker svcMap k8sp.ServicePortMap @@ -105,7 +105,7 @@ type proxy struct { // event recorder to update node events recorder events.EventRecorder svcHealthServer healthcheck.ServiceHealthServer - healthzServer healthcheck.ProxierHealthUpdater + healthzServer *healthcheck.ProxierHealthServer stopCh chan struct{} stopWg sync.WaitGroup @@ -154,20 +154,11 @@ func New(k8s kubernetes.Interface, dp DPSyncer, hostname string, opts ...Option) p.invokeDPSyncer, p.minDPSyncPeriod, time.Hour /* XXX might be infinite? */, 1) dp.SetTriggerFn(p.runner.Run) - nodeRef := &v1.ObjectReference{ - Kind: "Node", - Name: p.hostname, - UID: types.UID(p.hostname), - Namespace: "", - } - ipVersion := v1.IPv4Protocol - if p.ipFamily != 4 { - ipVersion = v1.IPv6Protocol - } - p.healthzServer = healthcheck.NewProxierHealthServer("0.0.0.0:10256", p.minDPSyncPeriod, p.recorder, nodeRef) + ipVersion := p.v1IPFamily() + p.healthzServer = healthcheck.NewProxierHealthServer("0.0.0.0:10256", p.minDPSyncPeriod) p.svcHealthServer = healthcheck.NewServiceHealthServer(p.hostname, p.recorder, util.NewNodePortAddresses(ipVersion, []string{"0.0.0.0/0"}), p.healthzServer) - p.epsChanges = k8sp.NewEndpointChangeTracker(p.hostname, + p.epsChanges = k8sp.NewEndpointsChangeTracker(p.hostname, nil, // change if you want to provide more ctx ipVersion, p.recorder, @@ -213,6 +204,15 @@ func New(k8s kubernetes.Interface, dp DPSyncer, hostname string, opts ...Option) return p, nil } +func (p *proxy) v1IPFamily() v1.IPFamily { + pr := v1.IPv4Protocol + if p.ipFamily != 4 { + pr = v1.IPv6Protocol + } + + return pr +} + func (p *proxy) setIpFamily(ipFamily int) { p.ipFamily = ipFamily } @@ -279,7 +279,7 @@ func (p *proxy) invokeDPSyncer() { } if p.healthzServer != nil { - p.healthzServer.Updated() + p.healthzServer.Updated(p.v1IPFamily()) } } @@ -303,18 +303,27 @@ func (p *proxy) OnServiceSynced() { } func (p *proxy) OnEndpointSliceAdd(eps *discovery.EndpointSlice) { + if p.IPFamily() != eps.AddressType { + return + } if p.epsChanges.EndpointSliceUpdate(eps, false) && p.isInitialized() { p.syncDP() } } func (p *proxy) OnEndpointSliceUpdate(_, eps *discovery.EndpointSlice) { + if p.IPFamily() != eps.AddressType { + return + } if p.epsChanges.EndpointSliceUpdate(eps, false) && p.isInitialized() { p.syncDP() } } func (p *proxy) OnEndpointSliceDelete(eps *discovery.EndpointSlice) { + if p.IPFamily() != eps.AddressType { + return + } if p.epsChanges.EndpointSliceUpdate(eps, true) && p.isInitialized() { p.syncDP() } @@ -334,6 +343,13 @@ func (p *proxy) SetSyncer(s DPSyncer) { p.forceSyncDP() } +func (p *proxy) IPFamily() discovery.AddressType { + if p.ipFamily == 4 { + return discovery.AddressTypeIPv4 + } + return discovery.AddressTypeIPv6 +} + type initState struct { lck sync.RWMutex svcsSynced bool diff --git a/felix/bpf/proxy/proxy_test.go b/felix/bpf/proxy/proxy_test.go index 72d119604b1..4614f0c83d1 100644 --- a/felix/bpf/proxy/proxy_test.go +++ b/felix/bpf/proxy/proxy_test.go @@ -342,7 +342,7 @@ var _ = Describe("BPF Proxy", func() { }] Expect(len(ep)).To(Equal(2)) - Expect(ep[0].GetIsLocal).NotTo(Equal(ep[1].GetIsLocal)) + Expect(ep[0].IsLocal()).NotTo(Equal(ep[1].IsLocal())) } }) }) @@ -506,7 +506,7 @@ var _ = Describe("BPF Proxy", func() { Expect(s.SvcMap).To(HaveLen(1)) for k := range s.SvcMap { for _, ep := range s.EpsMap[k] { - Expect(ep.GetIsLocal()).To(Equal(ep.String() == "10.1.2.1:1234")) + Expect(ep.IsLocal()).To(Equal(ep.String() == "10.1.2.1:1234")) } } }) diff --git a/felix/bpf/proxy/syncer.go b/felix/bpf/proxy/syncer.go index 7fa42f57462..e2e4413e42c 100644 --- a/felix/bpf/proxy/syncer.go +++ b/felix/bpf/proxy/syncer.go @@ -19,7 +19,6 @@ import ( "fmt" "net" "reflect" - "strconv" "strings" "sync" "time" @@ -369,10 +368,7 @@ func (s *Syncer) startupBuildPrev(state DPSyncerState) error { break } s.prevEpsMap[svckey.sname] = append(s.prevEpsMap[svckey.sname], - &k8sp.BaseEndpointInfo{ - Endpoint: net.JoinHostPort(ep.Addr().String(), strconv.Itoa(int(ep.Port()))), - // IsLocal is not important here - }, + NewEndpointInfo(ep.Addr().String(), int(ep.Port())), ) } }) @@ -443,7 +439,7 @@ func (s *Syncer) addActiveEps(id uint32, svc Service, eps []k8sp.Endpoint) { if ep.IsTerminating() && svc.Protocol() == v1.ProtocolUDP && svc.ReapTerminatingUDP() { continue // do not add this endpoint, treat it as if does not exist anymore } - port, _ := ep.Port() // it is error free by this point + port := ep.Port() // it is error free by this point epsmap[ipPort{ ip: ep.IP(), port: port, @@ -609,7 +605,7 @@ func (s *Syncer) apply(state DPSyncerState) error { eps := make([]k8sp.Endpoint, 0, len(state.EpsMap[sname])) for _, ep := range state.EpsMap[sname] { - zoneHints := ep.GetZoneHints() + zoneHints := ep.ZoneHints() if ep.IsReady() || ep.IsTerminating() { if ShouldAppendTopologyAwareEndpoint(nodeZone, hintsAnnotation, zoneHints) { eps = append(eps, ep) @@ -628,7 +624,7 @@ func (s *Syncer) apply(state DPSyncerState) error { return err } - for _, lbIP := range svc.LoadBalancerIPStrings() { + for _, lbIP := range svc.LoadBalancerVIPStrings() { if lbIP != "" { extInfo := serviceInfoFromK8sServicePort(svc) extInfo.clusterIP = net.ParseIP(lbIP) @@ -763,7 +759,7 @@ func (s *Syncer) updateService(skey svcKey, sinfo Service, id uint32, eps []k8sp } for _, ep := range eps { - if !ep.GetIsLocal() { + if !ep.IsLocal() { continue } @@ -780,7 +776,7 @@ func (s *Syncer) updateService(skey svcKey, sinfo Service, id uint32, eps []k8sp } for _, ep := range eps { - if ep.GetIsLocal() { + if ep.IsLocal() { continue } @@ -831,10 +827,7 @@ func (s *Syncer) writeSvcBackend(svcID uint32, idx uint32, ep k8sp.Endpoint) err key := nat.NewNATBackendKey(svcID, uint32(idx)) - tgtPort, err := ep.Port() - if err != nil { - return errors.Errorf("no port for endpoint %q: %s", ep, err) - } + tgtPort := ep.Port() val := s.newBackendValue(ip, uint16(tgtPort)) s.bpfEps.Desired().Set(key, val) @@ -1064,7 +1057,7 @@ func (s *Syncer) matchBpfSvc(bpfSvc nat.FrontendKeyInterface, k8sSvc k8sp.Servic } } - for _, lbip := range k8sInfo.LoadBalancerIPStrings() { + for _, lbip := range k8sInfo.LoadBalancerVIPStrings() { if lbip != "" { if bpfSvc.Addr().String() == lbip { if matchLBSrcIP() { @@ -1303,14 +1296,13 @@ func serviceInfoFromK8sServicePort(sport k8sp.ServicePort) *serviceInfo { sinfo.sessionAffinityType = sport.SessionAffinityType() sinfo.stickyMaxAgeSeconds = sport.StickyMaxAgeSeconds() sinfo.externalIPs = sport.ExternalIPStrings() - sinfo.loadBalancerIPStrings = sport.LoadBalancerIPStrings() + sinfo.loadBalancerVIPStrings = sport.LoadBalancerVIPStrings() sinfo.loadBalancerSourceRanges = sport.LoadBalancerSourceRanges() sinfo.healthCheckNodePort = sport.HealthCheckNodePort() sinfo.nodeLocalExternal = sport.ExternalPolicyLocal() sinfo.nodeLocalInternal = sport.InternalPolicyLocal() sinfo.hintsAnnotation = sport.HintsAnnotation() sinfo.internalTrafficPolicy = sport.InternalTrafficPolicy() - sinfo.servicePortAnnotations = sport.(*servicePort).servicePortAnnotations return sinfo @@ -1325,7 +1317,7 @@ type serviceInfo struct { stickyMaxAgeSeconds int externalIPs []string loadBalancerSourceRanges []string - loadBalancerIPStrings []string + loadBalancerVIPStrings []string healthCheckNodePort int nodeLocalExternal bool nodeLocalInternal bool @@ -1338,7 +1330,7 @@ type serviceInfo struct { // ExternallyAccessible returns true if the service port is reachable via something // other than ClusterIP (NodePort/ExternalIP/LoadBalancer) func (info *serviceInfo) ExternallyAccessible() bool { - return info.NodePort() != 0 || len(info.LoadBalancerIPStrings()) != 0 || len(info.ExternalIPStrings()) != 0 + return info.NodePort() != 0 || len(info.LoadBalancerVIPStrings()) != 0 || len(info.ExternalIPStrings()) != 0 } // UsesClusterEndpoints returns true if the service port ever sends traffic to @@ -1407,8 +1399,8 @@ func (info *serviceInfo) ExternalIPStrings() []string { } // LoadBalancerIPStrings is part of ServicePort interface. -func (info *serviceInfo) LoadBalancerIPStrings() []string { - return info.loadBalancerIPStrings +func (info *serviceInfo) LoadBalancerVIPStrings() []string { + return info.loadBalancerVIPStrings } // ExternalPolicyLocal returns if a service has only node local endpoints for external traffic. @@ -1469,7 +1461,7 @@ func ServicePortEqual(a, b k8sp.ServicePort) bool { a.HintsAnnotation() == b.HintsAnnotation() && a.InternalTrafficPolicy() == b.InternalTrafficPolicy() && stringsEqual(a.ExternalIPStrings(), b.ExternalIPStrings()) && - stringsEqual(a.LoadBalancerIPStrings(), b.LoadBalancerIPStrings()) && + stringsEqual(a.LoadBalancerVIPStrings(), b.LoadBalancerVIPStrings()) && stringsEqual(a.LoadBalancerSourceRanges(), b.LoadBalancerSourceRanges()) } @@ -1500,7 +1492,7 @@ func stringsEqual(a, b []string) bool { // K8sSvcWithLoadBalancerIPs set LoadBalancerIPStrings func K8sSvcWithLoadBalancerIPs(ips []string) K8sServicePortOption { return func(s interface{}) { - s.(*servicePort).ServicePort.(*serviceInfo).loadBalancerIPStrings = ips + s.(*servicePort).ServicePort.(*serviceInfo).loadBalancerVIPStrings = ips } } diff --git a/felix/bpf/proxy/syncer_bench_test.go b/felix/bpf/proxy/syncer_bench_test.go index 02cc3a2f793..8132927ea1c 100644 --- a/felix/bpf/proxy/syncer_bench_test.go +++ b/felix/bpf/proxy/syncer_bench_test.go @@ -46,7 +46,7 @@ func makeSvcEpsPair(svcIdx, epCnt, port int, opts ...K8sServicePortOption) (k8sp eps := make([]k8sp.Endpoint, epCnt) for j := 0; j < epCnt; j++ { - eps[j] = &k8sp.BaseEndpointInfo{Endpoint: fmt.Sprintf("11.1.1.1:%d", j+1)} + eps[j] = NewEndpointInfo("11.1.1.1", j+1) } return svc, eps @@ -93,7 +93,7 @@ func stateToBPFMaps(state DPSyncerState) ( Expect(err).NotTo(HaveOccurred()) for i, ep := range eps { - port, _ := ep.Port() + port := ep.Port() bk := nat.NewNATBackendKey(id, uint32(i)) bv := nat.NewNATBackendValue(net.ParseIP(ep.IP()), uint16(port)) err := be.Update(bk[:], bv[:]) diff --git a/felix/bpf/proxy/syncer_test.go b/felix/bpf/proxy/syncer_test.go index 53ab83afb93..322e1a1c79a 100644 --- a/felix/bpf/proxy/syncer_test.go +++ b/felix/bpf/proxy/syncer_test.go @@ -77,6 +77,7 @@ var _ = Describe("BPF Syncer", func() { s, _ = proxy.NewSyncer(4, nodeIPs, svcs, eps, aff, rt, nil) + ep := proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true)) state = proxy.DPSyncerState{ SvcMap: k8sp.ServicePortMap{ svcKey: proxy.NewK8sServicePort( @@ -86,7 +87,7 @@ var _ = Describe("BPF Syncer", func() { ), }, EpsMap: k8sp.EndpointsMap{ - svcKey: []k8sp.Endpoint{&k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555"}}, + svcKey: []k8sp.Endpoint{ep}, }, } }) @@ -146,10 +147,10 @@ var _ = Describe("BPF Syncer", func() { v1.ProtocolTCP, ) state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: false, Endpoint: "10.2.0.0:1111"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:1111"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: false, Endpoint: "10.2.0.3:1111"}, + proxy.NewEndpointInfo("10.2.0.0", 1111), + proxy.NewEndpointInfo("10.2.0.1", 1111, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.2.0.3", 1111), } err := s.Apply(state) @@ -229,7 +230,7 @@ var _ = Describe("BPF Syncer", func() { By("deleting one second-service backend", makestep(func() { state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:2222"}, + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -247,7 +248,7 @@ var _ = Describe("BPF Syncer", func() { By("terminating second-service backend", makestep(func() { state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: false, Terminating: true, Endpoint: "10.2.0.1:2222"}, + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsTerminating(true)), } err := s.Apply(state) @@ -264,7 +265,7 @@ var _ = Describe("BPF Syncer", func() { // Just that the rest of the test has the expected conditions. By("reviving one second-service backend", makestep(func() { state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:2222"}, + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -308,7 +309,7 @@ var _ = Describe("BPF Syncer", func() { } state.EpsMap[nosvcKey] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:6666"}, + proxy.NewEndpointInfo("10.2.0.1", 6666, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -463,7 +464,7 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithNodePort(3232), ) state.EpsMap[svcKey3] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.3.0.1:3434"}, + proxy.NewEndpointInfo("10.3.0.1", 3434, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -497,7 +498,7 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithNodePort(3232), ) state.EpsMap[svcKey3] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.3.0.1:3434"}, + proxy.NewEndpointInfo("10.3.0.1", 3434, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -529,7 +530,7 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithNodePort(1212), ) state.EpsMap[svcKey3] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.3.0.1:3434"}, + proxy.NewEndpointInfo("10.3.0.1", 3434, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -609,9 +610,9 @@ var _ = Describe("BPF Syncer", func() { ) state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.1.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.2.1:2222", IsLocal: true}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.3.1:2222"}, + proxy.NewEndpointInfo("10.2.1.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.2.2.1", 2222, proxy.EndpointInfoOptIsLocal(true), proxy.EndpointInfoOptIsReady(true)), // isLocal == true. + proxy.NewEndpointInfo("10.2.3.1", 2222, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -762,10 +763,10 @@ var _ = Describe("BPF Syncer", func() { ) state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.1.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.2.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.2.2:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.3.1:2222"}, + proxy.NewEndpointInfo("10.2.1.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.2.2.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.2.2.2", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.2.3.1", 2222, proxy.EndpointInfoOptIsReady(true)), } rt.Update( @@ -849,10 +850,10 @@ var _ = Describe("BPF Syncer", func() { ) state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.3.0.1:2222", IsLocal: true}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.4.0.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.5.0.1:2222", IsLocal: true}, + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.3.0.1", 2222, proxy.EndpointInfoOptIsLocal(true), proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.4.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.5.0.1", 2222, proxy.EndpointInfoOptIsLocal(true), proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -916,7 +917,7 @@ var _ = Describe("BPF Syncer", func() { ) state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:2222"}, + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), } err := s.Apply(state) @@ -932,8 +933,8 @@ var _ = Describe("BPF Syncer", func() { By("inserting another ep for service with affinity v1.ServiceAffinityClientIP", makestep(func() { state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.1:2222"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.3.0.1:3333"}, + proxy.NewEndpointInfo("10.2.0.1", 2222, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.3.0.1", 3333, proxy.EndpointInfoOptIsReady(true)), } // add active affinity entry @@ -973,7 +974,7 @@ var _ = Describe("BPF Syncer", func() { By("deleting an ep for service with affinity v1.ServiceAffinityClientIP", makestep(func() { state.EpsMap[svcKey2] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.3.0.1:3333"}, + proxy.NewEndpointInfo("10.3.0.1", 3333, proxy.EndpointInfoOptIsReady(true)), } err := aff.Update( @@ -1066,8 +1067,8 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithHintsAnnotation("auto"), ) state.EpsMap[svcKey] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555", ZoneHints: sets.New[string]("us-west-2a")}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.2:5555", ZoneHints: sets.New[string]("us-west-2b")}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2a"))), + proxy.NewEndpointInfo("10.2.0.2", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2b"))), } state.NodeZone = "us-west-2a" @@ -1084,8 +1085,8 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithHintsAnnotation("auto"), ) state.EpsMap[svcKey] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555", ZoneHints: sets.New[string]("us-west-2a")}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.2:5555", ZoneHints: sets.New[string]("us-west-2b")}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2a"))), + proxy.NewEndpointInfo("10.2.0.2", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2b"))), } state.NodeZone = "us-west-2b" @@ -1102,8 +1103,8 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithHintsAnnotation("disabled"), ) state.EpsMap[svcKey] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555", ZoneHints: sets.New[string]("us-west-2a")}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.2:5555", ZoneHints: sets.New[string]("us-west-2b")}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2a"))), + proxy.NewEndpointInfo("10.2.0.2", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2b"))), } state.NodeZone = "us-west-2b" @@ -1119,8 +1120,8 @@ var _ = Describe("BPF Syncer", func() { v1.ProtocolTCP, ) state.EpsMap[svcKey] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555", ZoneHints: sets.New[string]("us-west-2a")}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.2:5555", ZoneHints: sets.New[string]("us-west-2b")}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2a"))), + proxy.NewEndpointInfo("10.2.0.2", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2b"))), } state.NodeZone = "us-west-2b" @@ -1137,8 +1138,8 @@ var _ = Describe("BPF Syncer", func() { proxy.K8sSvcWithHintsAnnotation("auto"), ) state.EpsMap[svcKey] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555", ZoneHints: sets.New[string]("us-west-2a")}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.2.0.2:5555", ZoneHints: sets.New[string]("us-west-2b")}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2a"))), + proxy.NewEndpointInfo("10.2.0.2", 5555, proxy.EndpointInfoOptIsReady(true), proxy.EndpointInfoOptZoneHints(sets.New[string]("us-west-2b"))), } state.NodeZone = "" @@ -1164,9 +1165,9 @@ var _ = Describe("BPF Syncer", func() { v1.ProtocolTCP, ) state.EpsMap[svcKey4] = []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555"}, - &k8sp.BaseEndpointInfo{Terminating: true, Endpoint: "10.1.0.2:6666"}, - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.3:7777"}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.1.0.2", 6666, proxy.EndpointInfoOptIsTerminating(true)), + proxy.NewEndpointInfo("10.1.0.3", 7777, proxy.EndpointInfoOptIsReady(true)), } // Expect 2x new map entries for Ready pods only; Terminating pods not added to map. @@ -1217,8 +1218,8 @@ var _ = Describe("BPF Syncer", func() { }, EpsMap: k8sp.EndpointsMap{ svcKey: []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555"}, - &k8sp.BaseEndpointInfo{Terminating: true, Endpoint: "10.1.0.2:5555"}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.1.0.2", 5555, proxy.EndpointInfoOptIsTerminating(true)), }, }, } @@ -1254,8 +1255,8 @@ var _ = Describe("BPF Syncer", func() { }, EpsMap: k8sp.EndpointsMap{ svcKey: []k8sp.Endpoint{ - &k8sp.BaseEndpointInfo{Ready: true, Endpoint: "10.1.0.1:5555"}, - &k8sp.BaseEndpointInfo{Terminating: true, Endpoint: "10.1.0.2:5555"}, + proxy.NewEndpointInfo("10.1.0.1", 5555, proxy.EndpointInfoOptIsReady(true)), + proxy.NewEndpointInfo("10.1.0.2", 5555, proxy.EndpointInfoOptIsTerminating(true)), }, }, } @@ -1556,8 +1557,9 @@ func ctEntriesForSvc(ct maps.Map, proto v1.Protocol, p, _ = proxy.ProtoV1ToInt(v1.ProtocolTCP) } - epPort, err := ep.Port() - Expect(err).NotTo(HaveOccurred(), "Test failed to parse EP port") + // REVIEWER TODO: looking for sign-off on this adaptation. + epPort := ep.Port() + Expect(epPort).NotTo(BeNumerically("<=", 0), "Test failed to parse EP port") key := conntrack.NewKey(p, srcIP, srcPort, svcIP, svcPort) revKey := conntrack.NewKey(p, srcIP, srcPort, net.ParseIP(ep.IP()), uint16(epPort)) diff --git a/felix/bpf/tc/attach.go b/felix/bpf/tc/attach.go index e17610da68d..6448851fbdc 100644 --- a/felix/bpf/tc/attach.go +++ b/felix/bpf/tc/attach.go @@ -30,6 +30,7 @@ import ( "github.com/projectcalico/calico/felix/bpf/bpfdefs" "github.com/projectcalico/calico/felix/bpf/hook" "github.com/projectcalico/calico/felix/bpf/libbpf" + "github.com/projectcalico/calico/felix/bpf/maps" tcdefs "github.com/projectcalico/calico/felix/bpf/tc/defs" ) @@ -63,6 +64,7 @@ type AttachPoint struct { NATin uint32 NATout uint32 UDPOnly bool + RedirectPeer bool } var ErrDeviceNotFound = errors.New("device not found") @@ -99,6 +101,12 @@ func (ap *AttachPoint) loadObject(file string) (*libbpf.Obj, error) { continue } + if size := maps.Size(mapName); size != 0 { + if err := m.SetSize(size); err != nil { + return nil, fmt.Errorf("error resizing map %s: %w", mapName, err) + } + } + log.Debugf("Pinning map %s k %d v %d", mapName, m.KeySize(), m.ValueSize()) pinDir := bpf.MapPinDir(m.Type(), mapName, ap.Iface, ap.Hook) if err := m.SetPinPath(path.Join(pinDir, mapName)); err != nil { @@ -149,6 +157,7 @@ func (ap *AttachPoint) AttachProgram() (bpf.AttachResult, error) { return nil, err } + prio := findFilterPriority(progsToClean) obj, err := ap.loadObject(binaryToLoad) if err != nil { logCxt.Warn("Failed to load program") @@ -156,7 +165,7 @@ func (ap *AttachPoint) AttachProgram() (bpf.AttachResult, error) { } defer obj.Close() - res.progId, res.prio, res.handle, err = obj.AttachClassifier("cali_tc_preamble", ap.Iface, ap.Hook == hook.Ingress) + res.progId, res.prio, res.handle, err = obj.AttachClassifier("cali_tc_preamble", ap.Iface, ap.Hook == hook.Ingress, prio) if err != nil { logCxt.Warnf("Failed to attach to TC section cali_tc_preamble") return nil, err @@ -378,6 +387,21 @@ func RemoveQdisc(ifaceName string) error { return libbpf.RemoveQDisc(ifaceName) } +func findFilterPriority(progsToClean []attachedProg) int { + prio := 0 + for _, p := range progsToClean { + pref, err := strconv.Atoi(p.pref) + if err != nil { + continue + } + + if pref > prio { + prio = pref + } + } + return prio +} + func (ap *AttachPoint) Config() string { return fmt.Sprintf("%+v", ap) } @@ -422,6 +446,10 @@ func (ap *AttachPoint) ConfigureProgram(m *libbpf.Map) error { globalData.Flags |= libbpf.GlobalsLoUDPOnly } + if ap.RedirectPeer { + globalData.Flags |= libbpf.GlobalsRedirectPeer + } + globalData.HostTunnelIPv4 = globalData.HostIPv4 globalData.HostTunnelIPv6 = globalData.HostIPv6 diff --git a/felix/bpf/ut/attach_test.go b/felix/bpf/ut/attach_test.go index c3151f90842..4e9f22018bd 100644 --- a/felix/bpf/ut/attach_test.go +++ b/felix/bpf/ut/attach_test.go @@ -677,6 +677,235 @@ func TestAttach(t *testing.T) { runAttachTest(t, true) } +// This test simulates workload updates like changing labels, annotations. +// Expectation is that multiple workload updates should still result in +// preamble program not getting re-attached. +func TestAttachWithMultipleWorkloadUpdate(t *testing.T) { + RegisterTestingT(t) + + bpfmaps, err := bpfmap.CreateBPFMaps(false) + Expect(err).NotTo(HaveOccurred()) + + commonMaps := bpfmaps.CommonMaps + programs := commonMaps.ProgramsMap.(*hook.ProgramsMap) + loglevel := "off" + + bpfEpMgr, err := linux.NewTestEpMgr( + &linux.Config{ + Hostname: "uthost", + BPFLogLevel: loglevel, + BPFDataIfacePattern: regexp.MustCompile("^hostep[12]"), + VXLANMTU: 1000, + VXLANPort: 1234, + BPFNodePortDSREnabled: false, + RulesConfig: rules.Config{ + EndpointToHostAction: "RETURN", + }, + BPFExtToServiceConnmark: 0, + FeatureGates: map[string]string{ + "BPFConnectTimeLoadBalancingWorkaround": "enabled", + }, + BPFPolicyDebugEnabled: true, + }, + bpfmaps, + regexp.MustCompile("^workloadep[123]"), + ) + Expect(err).NotTo(HaveOccurred()) + + workload1 := createVethName("workloadep1") + defer deleteLink(workload1) + + bpfEpMgr.OnUpdate(&proto.HostMetadataUpdate{Hostname: "uthost", Ipv4Addr: "1.2.3.4"}) + bpfEpMgr.OnUpdate(linux.NewIfaceStateUpdate("workloadep1", ifacemonitor.StateUp, workload1.Attrs().Index)) + bpfEpMgr.OnUpdate(linux.NewIfaceAddrsUpdate("workloadep1", "1.6.6.6")) + bpfEpMgr.OnUpdate(&proto.WorkloadEndpointUpdate{ + Id: &proto.WorkloadEndpointID{ + OrchestratorId: "k8s", + WorkloadId: "workloadep1", + EndpointId: "workloadep1", + }, + Endpoint: &proto.WorkloadEndpoint{Name: "workloadep1"}, + }) + err = bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + + valid, firstPrio, firstHandle := bpfEpMgr.GetIfaceQDiscInfo("workloadep1") + Expect(valid).To(BeTrue()) + Expect(firstPrio).To(BeNumerically(">", 0)) + Expect(firstHandle).To(BeNumerically(">", 0)) + + at := programs.Programs() + Expect(at).To(HaveKey(hook.AttachType{ + Hook: hook.Ingress, + Family: 4, + Type: tcdefs.EpTypeWorkload, + LogLevel: loglevel, + FIB: true, + ToHostDrop: false, + DSR: false})) + Expect(at).To(HaveKey(hook.AttachType{ + Hook: hook.Egress, + Family: 4, + Type: tcdefs.EpTypeWorkload, + LogLevel: loglevel, + FIB: true, + ToHostDrop: false, + DSR: false})) + + // The expectation is that, WorkloadEndpointUpdates must not + // result in re-attaching the program. Hence the priority, handle of + // the tc filters must be the same. + for i := 0; i < 2; i++ { + bpfEpMgr.OnUpdate(&proto.WorkloadEndpointUpdate{ + Id: &proto.WorkloadEndpointID{ + OrchestratorId: "k8s", + WorkloadId: "workloadep1", + EndpointId: "workloadep1", + }, + Endpoint: &proto.WorkloadEndpoint{Name: "workloadep1"}, + }) + err = bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + valid, prio, handle := bpfEpMgr.GetIfaceQDiscInfo("workloadep1") + Expect(valid).To(BeTrue()) + Expect(prio).To(Equal(firstPrio)) + Expect(handle).To(Equal(firstHandle)) + } + +} + +// This test verifies that we use the same tc priority but toggle between +// handles when repeatedly attaching the preamble program. +func TestRepeatedAttach(t *testing.T) { + RegisterTestingT(t) + + iface, veth := createVeth() + defer func() { + deleteLink(veth) + }() + + ap := &tc.AttachPoint{ + AttachPoint: bpf.AttachPoint{ + Iface: iface, + Hook: hook.Ingress, + }, + HostIPv4: net.IPv4(8, 8, 8, 8), + IntfIPv4: net.IPv4(7, 7, 7, 7), + } + + _, err := tc.EnsureQdisc(iface) + Expect(err).NotTo(HaveOccurred(), "failed to create qdisc") + res, err := ap.AttachProgram() + Expect(err).NotTo(HaveOccurred(), "failed to attach preamble") + tcRes, ok := res.(tc.AttachResult) + Expect(ok).To(BeTrue()) + prio := tcRes.Prio() + handle := tcRes.Handle() + for i := 0; i < 3; i++ { + res, err = ap.AttachProgram() + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("failed to attach preamble : %d", i)) + tcRes, ok = res.(tc.AttachResult) + Expect(ok).To(BeTrue()) + Expect(tcRes.Prio()).To(Equal(prio)) + if i%2 == 0 { + Expect(tcRes.Handle()).To(Equal(handle + 1)) + } else { + Expect(tcRes.Handle()).To(Equal(handle)) + } + } +} + +func TestLogFilters(t *testing.T) { + RegisterTestingT(t) + + bpfmaps, err := bpfmap.CreateBPFMaps(false) + Expect(err).NotTo(HaveOccurred()) + + commonMaps := bpfmaps.CommonMaps + + cfg := linux.Config{ + Hostname: "uthost", + BPFLogLevel: "debug", + BPFDataIfacePattern: regexp.MustCompile("^hostep[12]"), + VXLANMTU: 1000, + VXLANPort: 1234, + BPFNodePortDSREnabled: false, + RulesConfig: rules.Config{ + EndpointToHostAction: "RETURN", + }, + BPFExtToServiceConnmark: 0, + FeatureGates: map[string]string{ + "BPFConnectTimeLoadBalancingWorkaround": "enabled", + }, + BPFPolicyDebugEnabled: true, + BPFLogFilters: map[string]string{"hostep1": "tcp"}, + } + + bpfEpMgr, err := linux.NewTestEpMgr( + &cfg, + bpfmaps, + regexp.MustCompile("^workloadep[0123]"), + ) + Expect(err).NotTo(HaveOccurred()) + + host1 := createVethName("hostep1") + defer deleteLink(host1) + + workload0 := createVethName("workloadep0") + defer deleteLink(workload0) + + t.Run("load filter", func(t *testing.T) { + bpfEpMgr.OnUpdate(linux.NewIfaceStateUpdate("hostep1", ifacemonitor.StateUp, host1.Attrs().Index)) + bpfEpMgr.OnUpdate(linux.NewIfaceStateUpdate("workloadep0", ifacemonitor.StateUp, workload0.Attrs().Index)) + bpfEpMgr.OnUpdate(linux.NewIfaceAddrsUpdate("hostep1", "1.2.3.4")) + bpfEpMgr.OnUpdate(&proto.HostMetadataUpdate{Hostname: "uthost", Ipv4Addr: "1.2.3.4"}) + err = bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + + ifstateMap := ifstateMapDump(commonMaps.IfStateMap) + + Expect(ifstateMap).To(HaveKey(ifstate.NewKey(uint32(host1.Attrs().Index)))) + hostep1State := ifstateMap[ifstate.NewKey(uint32(host1.Attrs().Index))] + Expect(hostep1State.TcIngressFilter()).NotTo(Equal(-1)) + Expect(hostep1State.TcEgressFilter()).NotTo(Equal(-1)) + + Expect(ifstateMap).To(HaveKey(ifstate.NewKey(uint32(workload0.Attrs().Index)))) + wl0State := ifstateMap[ifstate.NewKey(uint32(workload0.Attrs().Index))] + Expect(wl0State.TcIngressFilter()).To(Equal(-1)) + Expect(wl0State.TcEgressFilter()).To(Equal(-1)) + }) + + cfg.BPFLogLevel = "off" + + bpfEpMgr, err = linux.NewTestEpMgr( + &cfg, + bpfmaps, + regexp.MustCompile("^workloadep[0123]"), + ) + Expect(err).NotTo(HaveOccurred()) + + t.Run("after restart, load filter", func(t *testing.T) { + bpfEpMgr.OnUpdate(linux.NewIfaceStateUpdate("hostep1", ifacemonitor.StateUp, host1.Attrs().Index)) + bpfEpMgr.OnUpdate(linux.NewIfaceStateUpdate("workloadep0", ifacemonitor.StateUp, workload0.Attrs().Index)) + bpfEpMgr.OnUpdate(linux.NewIfaceAddrsUpdate("hostep1", "1.2.3.4")) + bpfEpMgr.OnUpdate(&proto.HostMetadataUpdate{Hostname: "uthost", Ipv4Addr: "1.2.3.4"}) + err = bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + + ifstateMap := ifstateMapDump(commonMaps.IfStateMap) + + Expect(ifstateMap).To(HaveKey(ifstate.NewKey(uint32(host1.Attrs().Index)))) + hostep1State := ifstateMap[ifstate.NewKey(uint32(host1.Attrs().Index))] + Expect(hostep1State.TcIngressFilter()).To(Equal(-1)) + Expect(hostep1State.TcEgressFilter()).To(Equal(-1)) + + Expect(ifstateMap).To(HaveKey(ifstate.NewKey(uint32(workload0.Attrs().Index)))) + wl0State := ifstateMap[ifstate.NewKey(uint32(workload0.Attrs().Index))] + Expect(wl0State.TcIngressFilter()).To(Equal(-1)) + Expect(wl0State.TcEgressFilter()).To(Equal(-1)) + }) +} + func ifstateMapDump(m maps.Map) ifstate.MapMem { ifstateMap := make(ifstate.MapMem) ifstateMapIter := ifstate.MapMemIter(ifstateMap) diff --git a/felix/bpf/ut/nat_test.go b/felix/bpf/ut/nat_test.go index cf8dff75e07..21837e89976 100644 --- a/felix/bpf/ut/nat_test.go +++ b/felix/bpf/ut/nat_test.go @@ -2741,10 +2741,10 @@ func TestNATHostRemoteNPLocalPod(t *testing.T) { err = rtMap.EnsureExists() Expect(err).NotTo(HaveOccurred()) defer resetRTMap(rtMap) - // backend it is a local workload + // backend is a local workload err = rtMap.Update( routes.NewKey(ip.CIDRFromIPNet(&wCIDR).(ip.V4CIDR)).AsBytes(), - routes.NewValue(routes.FlagsLocalWorkload).AsBytes(), + routes.NewValueWithIfIndex(routes.FlagsLocalWorkload, 1).AsBytes(), ) Expect(err).NotTo(HaveOccurred()) // destination is remote host diff --git a/felix/bpf/xdp/attach.go b/felix/bpf/xdp/attach.go index 1de3d943c4c..a4cde68aefe 100644 --- a/felix/bpf/xdp/attach.go +++ b/felix/bpf/xdp/attach.go @@ -26,6 +26,7 @@ import ( "github.com/projectcalico/calico/felix/bpf/bpfdefs" "github.com/projectcalico/calico/felix/bpf/hook" "github.com/projectcalico/calico/felix/bpf/libbpf" + "github.com/projectcalico/calico/felix/bpf/maps" tcdefs "github.com/projectcalico/calico/felix/bpf/tc/defs" ) @@ -166,7 +167,13 @@ func (ap *AttachPoint) AttachProgram() (bpf.AttachResult, error) { } continue } - // TODO: We need to set map size here like tc. + + if size := maps.Size(mapName); size != 0 { + if err := m.SetSize(size); err != nil { + return nil, fmt.Errorf("error resizing map %s: %w", mapName, err) + } + } + pinDir := bpf.MapPinDir(m.Type(), mapName, ap.Iface, hook.XDP) if err := m.SetPinPath(path.Join(pinDir, mapName)); err != nil { return nil, fmt.Errorf("error pinning map %s: %w", mapName, err) diff --git a/felix/calc/active_rules_calculator.go b/felix/calc/active_rules_calculator.go index fde9c3776ff..16490a1512e 100644 --- a/felix/calc/active_rules_calculator.go +++ b/felix/calc/active_rules_calculator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -58,7 +58,8 @@ type PolicyMatchListener interface { // The rules in a policy may also contain selectors; those are ignored here; they are // mapped to IP sets by the RuleScanner. type ActiveRulesCalculator struct { - // Caches of all known policies/profiles. + // Caches of all known tiers/policies/profiles. + allTiers map[string]*model.Tier allPolicies map[model.PolicyKey]*model.Policy allProfileRules map[string]*model.ProfileRules @@ -84,15 +85,16 @@ type ActiveRulesCalculator struct { // Callback objects. RuleScanner ruleScanner PolicyMatchListener PolicyMatchListener - OnPolicyCountsChanged func(numPolicies, numProfiles, numALPPolicies int) + OnPolicyCountsChanged func(numTiers, numPolicies, numProfiles, numALPPolicies int) OnAlive func() } func NewActiveRulesCalculator() *ActiveRulesCalculator { arc := &ActiveRulesCalculator{ - // Caches of all known policies/profiles. + // Caches of all known policies/profiles and tiers. allPolicies: make(map[model.PolicyKey]*model.Policy), allProfileRules: make(map[string]*model.ProfileRules), + allTiers: make(map[string]*model.Tier), allALPPolicies: set.New[model.PolicyKey](), @@ -114,8 +116,11 @@ func (arc *ActiveRulesCalculator) RegisterWith(localEndpointDispatcher, allUpdDi localEndpointDispatcher.Register(model.HostEndpointKey{}, arc.OnUpdate) // ...as well as all the policies and profiles. allUpdDispatcher.Register(model.PolicyKey{}, arc.OnUpdate) + allUpdDispatcher.Register(model.PolicyKey{}, arc.OnUpdate) allUpdDispatcher.Register(model.ProfileRulesKey{}, arc.OnUpdate) allUpdDispatcher.Register(model.ResourceKey{}, arc.OnUpdate) + // ... and tiers as well. only required for stats update. + allUpdDispatcher.Register(model.TierKey{}, arc.OnUpdate) allUpdDispatcher.RegisterStatusHandler(arc.OnStatusUpdate) } @@ -173,7 +178,7 @@ func (arc *ActiveRulesCalculator) OnUpdate(update api.Update) (_ bool) { log.Debugf("Profile rules deleted while inactive: %v", key.Name) } } - // Update the policy/profile counts. + // Update the tier/policy/profile counts. arc.updateStats() case model.PolicyKey: oldPolicy := arc.allPolicies[key] @@ -242,7 +247,18 @@ func (arc *ActiveRulesCalculator) OnUpdate(update api.Update) (_ bool) { arc.allALPPolicies.Discard(key) } } - // Update the policy/profile counts. + // Update the tier/policy/profile counts. + arc.updateStats() + case model.TierKey: + if update.Value != nil { + log.Debugf("Updating ARC for tier %v", key) + tier := update.Value.(*model.Tier) + arc.allTiers[key.Name] = tier + } else { + log.Debugf("Removing tier %v from ARC", key) + delete(arc.allTiers, key.Name) + } + // Update the tier/policy/profile counts. arc.updateStats() default: log.Infof("Ignoring unexpected update: %v %#v", @@ -268,7 +284,7 @@ func (arc *ActiveRulesCalculator) updateStats() { if arc.OnPolicyCountsChanged == nil { return } - arc.OnPolicyCountsChanged(len(arc.allPolicies), len(arc.allProfileRules), arc.allALPPolicies.Len()) + arc.OnPolicyCountsChanged(len(arc.allTiers), len(arc.allPolicies), len(arc.allProfileRules), arc.allALPPolicies.Len()) } func (arc *ActiveRulesCalculator) OnStatusUpdate(status api.SyncStatus) { diff --git a/felix/calc/calc_graph.go b/felix/calc/calc_graph.go index 7c50eb20176..41c31990270 100644 --- a/felix/calc/calc_graph.go +++ b/felix/calc/calc_graph.go @@ -192,18 +192,26 @@ func NewCalculationGraph(callbacks PipelineCallbacks, conf *config.Config, liveC // render into the dataplane. // // ... - // Dispatcher (all updates) - // / \ - // / \ All Host/Workload Endpoints - // / \ - // / Dispatcher (local updates) - // / | - // | Policies | Local Host/Workload Endpoints only - // | Profiles | - // | | - // Active Rules Calculator - // | - // | Locally active policies/profiles + // Dispatcher (all updates) + // /\ \ + // / \ \ All Host/Workload Endpoints + // / \ \ + // / \ Dispatcher (local updates) + // / \ | + // | \ \ Local Host/Workload + // | \ \ Endpoints only + // / \ \ \ + // Profiles / \ Policies \ \ + // / \ \ \ + // \ \ | \ + // \ \ |Tiers | + // \ \ | / + // \ | | / + // \ | | / + // \ | | / + // Active Rules Calculator + // | + // | Locally active policies/profiles // ... // activeRulesCalc := NewActiveRulesCalculator() diff --git a/felix/calc/calc_graph_fv_test.go b/felix/calc/calc_graph_fv_test.go index c4d228445d0..0e626b08cd9 100644 --- a/felix/calc/calc_graph_fv_test.go +++ b/felix/calc/calc_graph_fv_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -48,17 +48,50 @@ var baseTests = []StateList{ {}, // Add one endpoint then remove it and add another with overlapping IP. - {localEp1WithPolicy, localEp2WithPolicy}, + { + localEp1WithPolicy, + localEp2WithPolicy, + }, + + // Add one endpoint then remove it and add another with overlapping IP, + // with policy in a non-default tier. + { + localEp1WithPolicyAndTier, + localEp2WithPolicyAndTier, + }, // Same but ingress-only policy on ep1. {localEp1WithIngressPolicy, localEp2WithPolicy}, - // Add one endpoint then another with an overlapping IP, then remove - // first. - {localEp1WithPolicy, localEpsWithPolicy, localEp2WithPolicy}, + // Add one endpoint then another with an overlapping IP, then remove first. + { + localEp1WithPolicy, + localEpsWithPolicy, + localEp2WithPolicy, + }, + + // Add one endpoint then another with an overlapping IP, then remove first, + // with policies in none default tier. + { + localEp1WithPolicyAndTier, + localEpsWithPolicyAndTier, + localEp2WithPolicyAndTier, + }, + + // Add both endpoints, then return to empty, then add them both back. + { + localEpsWithPolicy, + initialisedStore, + localEpsWithPolicy, + }, // Add both endpoints, then return to empty, then add them both back. - {localEpsWithPolicy, initialisedStore, localEpsWithPolicy}, + // with policies in none default tier. + { + localEpsWithPolicyAndTier, + initialisedStore, + localEpsWithPolicyAndTier, + }, // IP updates. {localEpsWithPolicy, localEpsWithPolicyUpdatedIPs, localEp1WithIngressPolicy}, @@ -75,9 +108,43 @@ var baseTests = []StateList{ localEp1WithOneTierPolicyAlpha, }, + // Tests of policy ordering in a non-default tier. Each state has one tier but we shuffle + // the order of the policies within it. + { + commLocalEp1WithOneTierPolicy123, + commLocalEp1WithOneTierPolicy321, + commLocalEp1WithOneTierPolicyAlpha, + }, + // Test mutating the profile list of some endpoints. {localEpsWithNonMatchingProfile, localEpsWithProfile}, + // And tier ordering. + { + localEp1WithTiers123, + localEp1WithTiers321, + localEp1WithTiersAlpha, + localEp1WithTiersAlpha2, + localEp1WithTiers321, + localEp1WithTiersAlpha3, + }, + + // String together some complex updates with profiles and policies + // coming and going. + { + localEpsWithProfile, + commLocalEp1WithOneTierPolicy123, + localEp1WithTiers321, + localEpsWithNonMatchingProfile, + localEpsWithPolicyAndTier, + localEpsWithUpdatedProfile, + localEpsWithNonMatchingProfile, + localEpsWithUpdatedProfileNegatedTags, + localEp1WithPolicyAndTier, + localEp1WithTiersAlpha2, + localEpsWithProfile, + }, + // Host endpoint tests. {hostEp1WithPolicy, hostEp2WithPolicy, hostEp1WithIngressPolicy, hostEp1WithEgressPolicy}, @@ -854,6 +921,9 @@ func doStateSequenceTest(expandedTest StateList, flushStrategy flushStrategy) { expectCorrectDataplaneState(mockDataplane, state) // We only track stats in the sync tests. + Expect(lastStats.NumTiers).To(Equal(state.NumTiers()), + "number of tiers stat incorrect after moving to state: %v\n%+v", + state.Name, spew.Sdump(state.DatastoreState)) Expect(lastStats.NumPolicies).To(Equal(state.NumPolicies()), "number of policies stat incorrect after moving to state: %v\n%+v", state.Name, spew.Sdump(state.DatastoreState)) diff --git a/felix/calc/calc_graph_test.go b/felix/calc/calc_graph_test.go index 44107f29c5b..ce76ebccd5d 100644 --- a/felix/calc/calc_graph_test.go +++ b/felix/calc/calc_graph_test.go @@ -178,7 +178,7 @@ var _ = DescribeTable("Calculation graph pass-through tests", }, Spec: kapiv1.ServiceSpec{ Type: "ClusterIP", - ClusterIP: "10.96.0.1", + ClusterIPs: []string{"10.96.0.1"}, LoadBalancerIP: "1.1.1.1", ExternalIPs: []string{"1.2.3.4"}, Ports: []kapiv1.ServicePort{ @@ -196,7 +196,7 @@ var _ = DescribeTable("Calculation graph pass-through tests", Name: "svcname", Namespace: "default", Type: "ClusterIP", - ClusterIp: "10.96.0.1", + ClusterIps: []string{"10.96.0.1"}, LoadbalancerIp: "1.1.1.1", ExternalIps: []string{"1.2.3.4"}, Ports: []*proto.ServicePort{&udpPort, &tcpPort}, diff --git a/felix/calc/calc_suite_test.go b/felix/calc/calc_suite_test.go index ff24d0adc52..def7feaa1bd 100644 --- a/felix/calc/calc_suite_test.go +++ b/felix/calc/calc_suite_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,22 +15,17 @@ package calc_test import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "testing" + . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" - "github.com/sirupsen/logrus" + . "github.com/onsi/gomega" - "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/testutils" ) func init() { testutils.HookLogrusForGinkgo() - logrus.AddHook(&logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) } func TestCalculationGraph(t *testing.T) { diff --git a/felix/calc/dataplane_passthru.go b/felix/calc/dataplane_passthru.go index c8f1cd891cb..7ff95f13047 100644 --- a/felix/calc/dataplane_passthru.go +++ b/felix/calc/dataplane_passthru.go @@ -198,7 +198,7 @@ func kubernetesServiceToProto(s *kapiv1.Service) *proto.ServiceUpdate { Name: s.Name, Namespace: s.Namespace, Type: string(s.Spec.Type), - ClusterIp: s.Spec.ClusterIP, + ClusterIps: s.Spec.ClusterIPs, LoadbalancerIp: s.Spec.LoadBalancerIP, ExternalIps: s.Spec.ExternalIPs, } diff --git a/felix/calc/event_sequencer.go b/felix/calc/event_sequencer.go index ebe14aa3b18..411491f6a4c 100644 --- a/felix/calc/event_sequencer.go +++ b/felix/calc/event_sequencer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -304,7 +304,7 @@ func (buf *EventSequencer) flushPolicyUpdates() { func ParsedRulesToActivePolicyUpdate(key model.PolicyKey, rules *ParsedRules) *proto.ActivePolicyUpdate { return &proto.ActivePolicyUpdate{ Id: &proto.PolicyID{ - Tier: "default", + Tier: key.Tier, Name: key.Name, }, Policy: &proto.Policy{ @@ -335,7 +335,7 @@ func (buf *EventSequencer) flushPolicyDeletes() { buf.pendingPolicyDeletes.Iter(func(item model.PolicyKey) error { buf.Callback(&proto.ActivePolicyRemove{ Id: &proto.PolicyID{ - Tier: "default", + Tier: item.Tier, Name: item.Name, }, }) @@ -968,12 +968,27 @@ func (buf *EventSequencer) OnGlobalBGPConfigUpdate(cfg *v3.BGPConfiguration) { buf.pendingGlobalBGPConfig = &proto.GlobalBGPConfigUpdate{} if cfg != nil { for _, block := range cfg.Spec.ServiceClusterIPs { + if block.CIDR == "" { + // When we defined the CRD we allowed this field to be optional + // for extensibility, ignore empty CIDRs. + continue + } buf.pendingGlobalBGPConfig.ServiceClusterCidrs = append(buf.pendingGlobalBGPConfig.ServiceClusterCidrs, block.CIDR) } for _, block := range cfg.Spec.ServiceExternalIPs { + if block.CIDR == "" { + // When we defined the CRD we allowed this field to be optional + // for extensibility, ignore empty CIDRs. + continue + } buf.pendingGlobalBGPConfig.ServiceExternalCidrs = append(buf.pendingGlobalBGPConfig.ServiceExternalCidrs, block.CIDR) } for _, block := range cfg.Spec.ServiceLoadBalancerIPs { + if block.CIDR == "" { + // When we defined the CRD we allowed this field to be optional + // for extensibility, ignore empty CIDRs. + continue + } buf.pendingGlobalBGPConfig.ServiceLoadbalancerCidrs = append(buf.pendingGlobalBGPConfig.ServiceLoadbalancerCidrs, block.CIDR) } } @@ -1144,10 +1159,12 @@ func addPolicyToTierInfo(pol *PolKV, tierInfo *proto.TierInfo, egressAllowed boo func tierInfoToProtoTierInfo(filteredTiers []TierInfo) (normalTiers, untrackedTiers, preDNATTiers, forwardTiers []*proto.TierInfo) { if len(filteredTiers) > 0 { for _, ti := range filteredTiers { - untrackedTierInfo := &proto.TierInfo{Name: ti.Name} - preDNATTierInfo := &proto.TierInfo{Name: ti.Name} - forwardTierInfo := &proto.TierInfo{Name: ti.Name} - normalTierInfo := &proto.TierInfo{Name: ti.Name} + // For untracked and preDNAT tiers, DefautlAction must be Pass, to make sure policies in the normal tier + // are also checked. + untrackedTierInfo := &proto.TierInfo{Name: ti.Name, DefaultAction: string(v3.Pass)} + preDNATTierInfo := &proto.TierInfo{Name: ti.Name, DefaultAction: string(v3.Pass)} + forwardTierInfo := &proto.TierInfo{Name: ti.Name, DefaultAction: string(ti.DefaultAction)} + normalTierInfo := &proto.TierInfo{Name: ti.Name, DefaultAction: string(ti.DefaultAction)} for _, pol := range ti.OrderedPolicies { if pol.Value.DoNotTrack { addPolicyToTierInfo(&pol, untrackedTierInfo, true) diff --git a/felix/calc/event_sequencer_test.go b/felix/calc/event_sequencer_test.go index 5a18b098181..1652b52a92d 100644 --- a/felix/calc/event_sequencer_test.go +++ b/felix/calc/event_sequencer_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -129,7 +129,7 @@ var _ = Describe("ParsedRulesToActivePolicyUpdate", func() { }) It("should convert the fully-loaded rule", func() { - protoUpdate := calc.ParsedRulesToActivePolicyUpdate(model.PolicyKey{Name: "a-policy"}, &fullyLoadedParsedRules) + protoUpdate := calc.ParsedRulesToActivePolicyUpdate(model.PolicyKey{Tier: "default", Name: "a-policy"}, &fullyLoadedParsedRules) // Check the rule IDs are filled in but ignore them for comparisons. for _, r := range protoUpdate.Policy.InboundRules { Expect(r.RuleId).ToNot(Equal("")) diff --git a/felix/calc/policy_resolver.go b/felix/calc/policy_resolver.go index 2ff407cdde8..b232fc156ac 100644 --- a/felix/calc/policy_resolver.go +++ b/felix/calc/policy_resolver.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ type PolicyResolver struct { policyIDToEndpointIDs multidict.Multidict[model.PolicyKey, any] endpointIDToPolicyIDs multidict.Multidict[any, model.PolicyKey] allPolicies map[model.PolicyKey]*model.Policy - sortedTierData *TierInfo + sortedTierData []*TierInfo endpoints map[model.Key]interface{} dirtyEndpoints set.Set[any] /* FIXME model.WorkloadEndpointKey or model.HostEndpointKey */ policySorter *PolicySorter @@ -70,7 +70,6 @@ func NewPolicyResolver() *PolicyResolver { policyIDToEndpointIDs: multidict.New[model.PolicyKey, any](), endpointIDToPolicyIDs: multidict.New[any, model.PolicyKey](), allPolicies: map[model.PolicyKey]*model.Policy{}, - sortedTierData: NewTierInfo("default"), endpoints: make(map[model.Key]interface{}), dirtyEndpoints: set.New[any](), policySorter: NewPolicySorter(), @@ -79,13 +78,13 @@ func NewPolicyResolver() *PolicyResolver { func (pr *PolicyResolver) RegisterWith(allUpdDispatcher, localEndpointDispatcher *dispatcher.Dispatcher) { allUpdDispatcher.Register(model.PolicyKey{}, pr.OnUpdate) + allUpdDispatcher.Register(model.TierKey{}, pr.OnUpdate) localEndpointDispatcher.Register(model.WorkloadEndpointKey{}, pr.OnUpdate) localEndpointDispatcher.Register(model.HostEndpointKey{}, pr.OnUpdate) localEndpointDispatcher.RegisterStatusHandler(pr.OnDatamodelStatus) } func (pr *PolicyResolver) OnUpdate(update api.Update) (filterOut bool) { - policiesDirty := false switch key := update.Key.(type) { case model.WorkloadEndpointKey, model.HostEndpointKey: if update.Value != nil { @@ -106,10 +105,14 @@ func (pr *PolicyResolver) OnUpdate(update api.Update) (filterOut bool) { if !pr.policyIDToEndpointIDs.ContainsKey(key) { return } - policiesDirty = pr.policySorter.OnUpdate(update) + policiesDirty := pr.policySorter.OnUpdate(update) if policiesDirty { pr.markEndpointsMatchingPolicyDirty(key) } + case model.TierKey: + log.Debugf("Tier update: %v", key) + pr.policySorter.OnUpdate(update) + pr.markAllEndpointsDirty() } gaugeNumActivePolicies.Set(float64(pr.policyIDToEndpointIDs.Len())) return @@ -121,6 +124,13 @@ func (pr *PolicyResolver) OnDatamodelStatus(status api.SyncStatus) { } } +func (pr *PolicyResolver) markAllEndpointsDirty() { + log.Debugf("Marking all endpoints dirty") + pr.endpointIDToPolicyIDs.IterKeys(func(epID interface{}) { + pr.dirtyEndpoints.Add(epID) + }) +} + func (pr *PolicyResolver) markEndpointsMatchingPolicyDirty(polKey model.PolicyKey) { log.Debugf("Marking all endpoints matching %v dirty", polKey) pr.policyIDToEndpointIDs.Iter(polKey, func(epID interface{}) { @@ -168,32 +178,38 @@ func (pr *PolicyResolver) sendEndpointUpdate(endpointID interface{}) error { endpoint, ok := pr.endpoints[endpointID.(model.Key)] if !ok { log.Debugf("Endpoint is unknown, sending nil update") - pr.Callbacks.OnEndpointTierUpdate(endpointID.(model.Key), - nil, []TierInfo{}) + pr.Callbacks.OnEndpointTierUpdate(endpointID.(model.Key), nil, []TierInfo{}) return nil } + applicableTiers := []TierInfo{} - tier := pr.sortedTierData - tierMatches := false - filteredTier := TierInfo{ - Name: tier.Name, - Order: tier.Order, - } - for _, polKV := range tier.OrderedPolicies { - log.Debugf("Checking if policy %v matches %v", polKV.Key, endpointID) - if pr.endpointIDToPolicyIDs.Contains(endpointID, polKV.Key) { - log.Debugf("Policy %v matches %v", polKV.Key, endpointID) - tierMatches = true - filteredTier.OrderedPolicies = append(filteredTier.OrderedPolicies, - polKV) + for _, tier := range pr.sortedTierData { + if !tier.Valid { + log.Debugf("Tier %v invalid, skipping", tier.Name) + } + tierMatches := false + filteredTier := TierInfo{ + Name: tier.Name, + Order: tier.Order, + DefaultAction: tier.DefaultAction, + Valid: true, + } + for _, polKV := range tier.OrderedPolicies { + log.Debugf("Checking if policy %v matches %v", polKV.Key, endpointID) + if pr.endpointIDToPolicyIDs.Contains(endpointID, polKV.Key) { + log.Debugf("Policy %v matches %v", polKV.Key, endpointID) + tierMatches = true + filteredTier.OrderedPolicies = append(filteredTier.OrderedPolicies, + polKV) + } + } + if tierMatches { + log.Debugf("Tier %v matches %v", tier.Name, endpointID) + applicableTiers = append(applicableTiers, filteredTier) } } - if tierMatches { - log.Debugf("Tier %v matches %v", tier.Name, endpointID) - applicableTiers = append(applicableTiers, filteredTier) - } + log.Debugf("Endpoint tier update: %v -> %v", endpointID, applicableTiers) - pr.Callbacks.OnEndpointTierUpdate(endpointID.(model.Key), - endpoint, applicableTiers) + pr.Callbacks.OnEndpointTierUpdate(endpointID.(model.Key), endpoint, applicableTiers) return nil } diff --git a/felix/calc/policy_resolver_test.go b/felix/calc/policy_resolver_test.go index 907592aa1e0..9e9d0bb82ad 100644 --- a/felix/calc/policy_resolver_test.go +++ b/felix/calc/policy_resolver_test.go @@ -1,3 +1,17 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package calc import ( @@ -81,6 +95,7 @@ func TestPolicyResolver_OnPolicyMatch(t *testing.T) { pr, recorder := createPolicyResolver() polKey := model.PolicyKey{ + Tier: "default", Name: "test-policy", } @@ -89,7 +104,10 @@ func TestPolicyResolver_OnPolicyMatch(t *testing.T) { endpointKey := model.WorkloadEndpointKey{ Hostname: "test-workload-ep", } - pr.endpoints[endpointKey] = "the endpoint" + wep := &model.WorkloadEndpoint{ + Name: "we1", + } + pr.endpoints[endpointKey] = wep pr.allPolicies[polKey] = &pol @@ -123,9 +141,10 @@ func TestPolicyResolver_OnPolicyMatch(t *testing.T) { } if d := cmp.Diff(recorder.updates[0], policyResolverUpdate{ Key: endpointKey, - Endpoint: "the endpoint", + Endpoint: wep, Tiers: []TierInfo{{ - Name: "default", + Name: "default", + Valid: true, OrderedPolicies: []PolKV{ { Key: polKey, @@ -143,6 +162,7 @@ func TestPolicyResolver_OnPolicyMatchStopped(t *testing.T) { pr.OnDatamodelStatus(api.InSync) polKey := model.PolicyKey{ + Tier: "default", Name: "test-policy", } diff --git a/felix/calc/policy_sorter.go b/felix/calc/policy_sorter.go index f41865a2836..6c4c090cb4f 100644 --- a/felix/calc/policy_sorter.go +++ b/felix/calc/policy_sorter.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,6 +19,9 @@ import ( "strings" "github.com/google/btree" + "github.com/sirupsen/logrus" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/calico/libcalico-go/lib/backend/api" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" @@ -26,16 +29,14 @@ import ( ) type PolicySorter struct { - Tier *TierInfo + tiers map[string]*TierInfo + sortedTiers *btree.BTreeG[tierInfoKey] } func NewPolicySorter() *PolicySorter { return &PolicySorter{ - Tier: &TierInfo{ - Name: "default", - Policies: make(map[model.PolicyKey]*model.Policy), - SortedPolicies: btree.NewG[PolKV](2, PolKVLess), - }, + tiers: make(map[string]*TierInfo), + sortedTiers: btree.NewG(2, TierLess), } } @@ -51,17 +52,96 @@ func policyTypesEqual(pol1, pol2 *model.Policy) bool { return types1.Equals(types2) } -func (poc *PolicySorter) Sorted() *TierInfo { - poc.Tier.OrderedPolicies = make([]PolKV, 0, len(poc.Tier.Policies)) - poc.Tier.SortedPolicies.Ascend(func(kv PolKV) bool { - poc.Tier.OrderedPolicies = append(poc.Tier.OrderedPolicies, kv) - return true - }) - return poc.Tier +func (poc *PolicySorter) Sorted() []*TierInfo { + var tiers []*TierInfo + if poc.sortedTiers.Len() > 0 { + tiers = make([]*TierInfo, 0, len(poc.tiers)) + poc.sortedTiers.Ascend(func(t tierInfoKey) bool { + if ti := poc.tiers[t.Name]; ti != nil { + if ti.SortedPolicies != nil { + ti.OrderedPolicies = make([]PolKV, 0, len(ti.Policies)) + ti.SortedPolicies.Ascend(func(kv PolKV) bool { + ti.OrderedPolicies = append(ti.OrderedPolicies, kv) + return true + }) + } + tiers = append(tiers, ti) + return true + } else { + // A key for a tier that isn't found in the map is highly unexpected so panic + logrus.WithField("name", t.Name).Panic("Bug: tier present in map but not the sorted tree.") + return false + } + }) + } + return tiers } func (poc *PolicySorter) OnUpdate(update api.Update) (dirty bool) { switch key := update.Key.(type) { + case model.TierKey: + tierName := key.Name + logCxt := logrus.WithField("tierName", tierName) + tierInfo := poc.tiers[tierName] + if update.Value != nil { + newTier := update.Value.(*model.Tier) + logCxt.WithFields(logrus.Fields{ + "order": newTier.Order, + "defaultAction": newTier.DefaultAction, + }).Debug("Tier update") + if tierInfo == nil { + tierInfo = NewTierInfo(key.Name) + poc.tiers[tierName] = tierInfo + dirty = true + } else { + oldKey := tierInfoKey{ + Name: tierInfo.Name, + Order: tierInfo.Order, + Valid: tierInfo.Valid, + } + poc.sortedTiers.Delete(oldKey) + } + if tierInfo.Order != newTier.Order { + tierInfo.Order = newTier.Order + dirty = true + } + if tierInfo.DefaultAction != newTier.DefaultAction { + tierInfo.DefaultAction = newTier.DefaultAction + dirty = true + } + tierInfo.Valid = true + newKey := tierInfoKey{ + Name: tierInfo.Name, + Order: tierInfo.Order, + Valid: tierInfo.Valid, + } + poc.sortedTiers.ReplaceOrInsert(newKey) + } else { + // Deletion. + if tierInfo != nil { + oldKey := tierInfoKey{ + Name: tierInfo.Name, + Order: tierInfo.Order, + Valid: tierInfo.Valid, + } + poc.sortedTiers.Delete(oldKey) + tierInfo.Valid = false + tierInfo.Order = nil + if len(tierInfo.Policies) == 0 { + delete(poc.tiers, tierName) + } else { + // Add back so that sort order is maintained correctly after manipulating Valid and + // Order fields above + newKey := tierInfoKey{ + Name: tierInfo.Name, + Order: tierInfo.Order, + Valid: tierInfo.Valid, + } + poc.sortedTiers.ReplaceOrInsert(newKey) + } + dirty = true + } + } case model.PolicyKey: var newPolicy *model.Policy if update.Value != nil { @@ -74,14 +154,51 @@ func (poc *PolicySorter) OnUpdate(update api.Update) (dirty bool) { return } -func (poc *PolicySorter) HasPolicy(key model.PolicyKey) (found bool) { - _, found = poc.Tier.Policies[key] +func TierLess(i, j tierInfoKey) bool { + if !i.Valid && j.Valid { + return false + } else if i.Valid && !j.Valid { + return true + } + if i.Order == nil && j.Order != nil { + return false + } else if i.Order != nil && j.Order == nil { + return true + } + if i.Order == j.Order || *i.Order == *j.Order { + return i.Name < j.Name + } + return *i.Order < *j.Order +} + +func (poc *PolicySorter) HasPolicy(key model.PolicyKey) bool { + var tierInfo *TierInfo + var found bool + if tierInfo, found = poc.tiers[key.Tier]; found { + _, found = tierInfo.Policies[key] + } return found } func (poc *PolicySorter) UpdatePolicy(key model.PolicyKey, newPolicy *model.Policy) (dirty bool) { - oldPolicy := poc.Tier.Policies[key] + tierInfo := poc.tiers[key.Tier] + var tiKey tierInfoKey + var oldPolicy *model.Policy + if tierInfo != nil { + oldPolicy = tierInfo.Policies[key] + tiKey.Name = tierInfo.Name + tiKey.Order = tierInfo.Order + tiKey.Valid = tierInfo.Valid + } if newPolicy != nil { + if tierInfo == nil { + tierInfo = NewTierInfo(key.Tier) + tiKey.Name = tierInfo.Name + tiKey.Valid = tierInfo.Valid + tiKey.Order = tierInfo.Order + poc.tiers[key.Tier] = tierInfo + poc.sortedTiers.ReplaceOrInsert(tiKey) + } if oldPolicy == nil || oldPolicy.Order != newPolicy.Order || oldPolicy.DoNotTrack != newPolicy.DoNotTrack || @@ -95,18 +212,21 @@ func (poc *PolicySorter) UpdatePolicy(key model.PolicyKey, newPolicy *model.Poli // combination of key + value so if for instance we add PolKV{k1, v1} then add PolKV{k1, v2} we'll simply have // both KVs in the tree instead of only {k1, v2} like we want. By deleting first we guarantee that only the // newest value remains in the tree. - poc.Tier.SortedPolicies.Delete(PolKV{Key: key, Value: oldPolicy}) + tierInfo.SortedPolicies.Delete(PolKV{Key: key, Value: oldPolicy}) } - poc.Tier.SortedPolicies.ReplaceOrInsert(PolKV{Key: key, Value: newPolicy}) - poc.Tier.Policies[key] = newPolicy + tierInfo.SortedPolicies.ReplaceOrInsert(PolKV{Key: key, Value: newPolicy}) + tierInfo.Policies[key] = newPolicy } else { - if oldPolicy != nil { - poc.Tier.SortedPolicies.Delete(PolKV{Key: key, Value: oldPolicy}) - delete(poc.Tier.Policies, key) + if tierInfo != nil && oldPolicy != nil { + tierInfo.SortedPolicies.Delete(PolKV{Key: key, Value: oldPolicy}) + delete(tierInfo.Policies, key) + if len(tierInfo.Policies) == 0 && !tierInfo.Valid { + poc.sortedTiers.Delete(tiKey) + delete(poc.tiers, key.Tier) + } dirty = true } } - return } @@ -121,7 +241,7 @@ type PolKV struct { egress *bool } -func (p PolKV) String() string { +func (p *PolKV) String() string { orderStr := "nil policy" if p.Value != nil { if p.Value.Order != nil { @@ -133,7 +253,7 @@ func (p PolKV) String() string { return fmt.Sprintf("%s(%s)", p.Key.Name, orderStr) } -func (p PolKV) governsType(wanted string) bool { +func (p *PolKV) governsType(wanted string) bool { // Back-compatibility: no Types means Ingress and Egress. if len(p.Value.Types) == 0 { return true @@ -146,7 +266,7 @@ func (p PolKV) governsType(wanted string) bool { return false } -func (p PolKV) GovernsIngress() bool { +func (p *PolKV) GovernsIngress() bool { if p.ingress == nil { governsIngress := p.governsType("ingress") p.ingress = &governsIngress @@ -154,7 +274,7 @@ func (p PolKV) GovernsIngress() bool { return *p.ingress } -func (p PolKV) GovernsEgress() bool { +func (p *PolKV) GovernsEgress() bool { if p.egress == nil { governsEgress := p.governsType("egress") p.egress = &governsEgress @@ -169,8 +289,7 @@ func PolKVLess(i, j PolKV) bool { if ordersEqual { // Use name as tie-break. - result := i.Key.Name < j.Key.Name - return result + return i.Key.Name < j.Key.Name } // nil order maps to "infinity" @@ -188,15 +307,23 @@ type TierInfo struct { Name string Valid bool Order *float64 + DefaultAction v3.Action Policies map[model.PolicyKey]*model.Policy SortedPolicies *btree.BTreeG[PolKV] OrderedPolicies []PolKV } +type tierInfoKey struct { + Name string + Valid bool + Order *float64 +} + func NewTierInfo(name string) *TierInfo { return &TierInfo{ - Name: name, - Policies: make(map[model.PolicyKey]*model.Policy), + Name: name, + Policies: make(map[model.PolicyKey]*model.Policy), + SortedPolicies: btree.NewG[PolKV](2, PolKVLess), } } diff --git a/felix/calc/policy_sorter_test.go b/felix/calc/policy_sorter_test.go index 4bc8e84b538..d768134ac36 100644 --- a/felix/calc/policy_sorter_test.go +++ b/felix/calc/policy_sorter_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package calc_test +package calc import ( + "reflect" "testing" - . "github.com/projectcalico/calico/felix/calc" "github.com/projectcalico/calico/libcalico-go/lib/backend/api" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" @@ -27,6 +27,10 @@ var ( tenPointFive = 10.5 ) +func floatPtr(f float64) *float64 { + return &f +} + func TestPolKV_String(t *testing.T) { type kvTestType struct { name string @@ -64,38 +68,23 @@ func TestPolKV_String(t *testing.T) { } } -func TestPolicySorter_OnUpdate(t *testing.T) { +func TestPolicySorter_HasPolicy(t *testing.T) { poc := NewPolicySorter() - - policy := model.Policy{} - kvp := model.KVPair{ - Key: model.PolicyKey{ - Name: "test-policy", - }, - Value: &policy, - } - update := api.Update{} - update.Key = kvp.Key - update.Value = kvp.Value - - dirty := poc.OnUpdate(update) - if !dirty { - t.Error("Update containing new policy - expected dirty to be true but it was false") + polKey := model.PolicyKey{ + Name: "test-policy", + Tier: "test-tier", } - - update.Value = nil - - dirty = poc.OnUpdate(update) - if !dirty { - t.Error("Update containing empty value for existing policy - expected dirty to be true but it was false") + found := poc.HasPolicy(polKey) + if found { + t.Error("Unexpectedly found policy when it should not be present") } - update.Value = kvp.Value - update.Key = model.HostEndpointKey{} + pol := model.Policy{} + _ = poc.UpdatePolicy(polKey, &pol) - dirty = poc.OnUpdate(update) - if dirty { - t.Error("Update containing key type other than PolicyKey - expected dirty to be false but it was true") + found = poc.HasPolicy(polKey) + if !found { + t.Error("Policy that should be present was not found") } } @@ -104,21 +93,26 @@ func TestPolicySorter_UpdatePolicy(t *testing.T) { polKey := model.PolicyKey{ Name: "test-policy", + Tier: "default", } pol := model.Policy{} dirty := poc.UpdatePolicy(polKey, &pol) - if !dirty { - t.Error("Adding new policy - expected dirty to be true but it was false") - } - if _, found := poc.Tier.Policies[polKey]; !found { - t.Error("Adding new policy - expected policy to be in Policies but it is not") + if tierInfo, found := poc.tiers[polKey.Tier]; !found { + t.Error("Adding new policy to tier that does not yet exist - expected tier to be created but it is not found") + } else { + if !dirty { + t.Error("Adding new policy - expected dirty to be true but it was false") + } + if _, found = tierInfo.Policies[polKey]; !found { + t.Error("Adding new policy - expected policy to be in Policies but it is not") + } } - newOrder := float64(7) - newPol := model.Policy{} - newPol.Order = &newOrder + newPol := model.Policy{ + Order: floatPtr(7), + } dirty = poc.UpdatePolicy(polKey, &newPol) if !dirty { @@ -162,8 +156,11 @@ func TestPolicySorter_UpdatePolicy(t *testing.T) { if !dirty { t.Error("Deleting existing policy - expected dirty to be true but it was false") } - if _, found := poc.Tier.Policies[polKey]; found { - t.Error("Deleting existing policy - expected policy not to be in Policies but it is") + + if tierInfo, found := poc.tiers[polKey.Tier]; found { + if _, found = tierInfo.Policies[polKey]; found { + t.Error("Deleting existing policy - expected policy not to be in Policies but it is") + } } dirty = poc.UpdatePolicy(polKey, nil) @@ -172,21 +169,328 @@ func TestPolicySorter_UpdatePolicy(t *testing.T) { } } -func TestPolicySorter_HasPolicy(t *testing.T) { +func TestPolicySorter_OnUpdate_Basic(t *testing.T) { poc := NewPolicySorter() - polKey := model.PolicyKey{ - Name: "test-policy", + + policy := model.Policy{} + kvp := model.KVPair{ + Key: model.PolicyKey{ + Name: "test-policy", + Tier: "default", + }, + Value: &policy, } - found := poc.HasPolicy(polKey) - if found { - t.Error("Unexpectedly found policy when it should not be present") + update := api.Update{} + update.Key = kvp.Key + update.Value = kvp.Value + + dirty := poc.OnUpdate(update) + if !dirty { + t.Error("Update containing new policy - expected dirty to be true but it was false") } - pol := model.Policy{} - _ = poc.UpdatePolicy(polKey, &pol) + update.Value = nil - found = poc.HasPolicy(polKey) - if !found { - t.Error("Policy that should be present was not found") + dirty = poc.OnUpdate(update) + if !dirty { + t.Error("Update containing empty value for existing policy - expected dirty to be true but it was false") + } + + update.Value = kvp.Value + update.Key = model.HostEndpointKey{} + + dirty = poc.OnUpdate(update) + if dirty { + t.Error("Update containing key type other than PolicyKey - expected dirty to be false but it was true") + } +} + +func TestPolicySorter_OnUpdate_RemoveFromNonExistent(t *testing.T) { + ps := NewPolicySorter() + key := model.PolicyKey{Tier: "default", Name: "foo"} + pol := &model.Policy{} + ps.OnUpdate(api.Update{ + KVPair: model.KVPair{ + Key: key, + Value: pol, + }, + }) + + if ps.tiers["default"].Valid { + t.Error("Expected default tier not to be valid but it is") + } + + expectedPolicies := map[model.PolicyKey]*model.Policy{ + key: pol, + } + + if !reflect.DeepEqual(ps.tiers["default"].Policies, expectedPolicies) { + t.Errorf("Expected %v \n to equal \n %v", ps.tiers["default"].Policies, expectedPolicies) + } + + ps.OnUpdate(api.Update{ + KVPair: model.KVPair{ + Key: key, + Value: nil, // deletion + }, + }) + + if _, found := ps.tiers["default"]; found { + t.Error("Expected default tier not to exist but it does") + } +} + +func TestPolicySorter_OnUpdate_Remove(t *testing.T) { + ps := NewPolicySorter() + key := model.TierKey{Name: "default"} + tier := &model.Tier{} + ps.OnUpdate(api.Update{ + KVPair: model.KVPair{ + Key: key, + Value: tier, + }, + }) + + if !ps.tiers["default"].Valid { + t.Error("Expected default tier to be valid but it is not") + } + + if len(ps.tiers["default"].Policies) > 0 { + t.Error("Expected default tier to be empty but it is not") + } + + ps.OnUpdate(api.Update{ + KVPair: model.KVPair{ + Key: key, + Value: nil, // deletion + }, + }) + + if _, found := ps.tiers["default"]; found { + t.Error("Expected default tier not to exist but it does") + } +} + +func TestPolicySorter_Sorting(t *testing.T) { + type sortingTestType struct { + name string + input []*TierInfo + expected []*TierInfo + } + + tests := []sortingTestType{ + { + name: "nil", + input: []*TierInfo(nil), + expected: []*TierInfo(nil), + }, + { + name: "empty", + input: []*TierInfo{}, + expected: []*TierInfo(nil), + }, + { + name: "valid sorts ahead of invalid", + input: []*TierInfo{ + { + Name: "bar", + Valid: false, + Order: floatPtr(1), + }, + { + Name: "foo", + Valid: true, + Order: floatPtr(10), + }, + }, + expected: []*TierInfo{ + { + Name: "foo", + Valid: true, + Order: floatPtr(10), + }, + { + Name: "bar", + Valid: false, + Order: floatPtr(1), + }, + }, + }, + { + name: "both invalid, both nil order rely on name", + input: []*TierInfo{ + { + Name: "foo", + Valid: false, + }, + { + Name: "bar", + Valid: false, + }, + }, + expected: []*TierInfo{ + { + Name: "bar", + Valid: false, + }, + { + Name: "foo", + Valid: false, + }, + }, + }, + { + name: "both valid, both nil order rely on name", + input: []*TierInfo{ + { + Name: "foo", + Valid: true, + }, + { + Name: "bar", + Valid: true, + }, + }, + expected: []*TierInfo{ + { + Name: "bar", + Valid: true, + }, + { + Name: "foo", + Valid: true, + }, + }, + }, + { + name: "both valid, rely on order", + input: []*TierInfo{ + { + Name: "bar", + Order: floatPtr(10), + Valid: true, + }, + { + Name: "foo", + Order: floatPtr(1), + Valid: true, + }, + }, + expected: []*TierInfo{ + { + Name: "foo", + Order: floatPtr(1), + Valid: true, + }, + { + Name: "bar", + Order: floatPtr(10), + Valid: true, + }, + }, + }, + { + name: "all valid, non-nil orders sort ahead of nil", + input: []*TierInfo{ + { + Name: "bar", + Valid: true, + }, + { + Name: "baz", + Order: floatPtr(10), + Valid: true, + }, + { + Name: "foo", + Order: floatPtr(1), + Valid: true, + }, + }, + expected: []*TierInfo{ + { + Name: "foo", + Order: floatPtr(1), + Valid: true, + }, + { + Name: "baz", + Order: floatPtr(10), + Valid: true, + }, + { + Name: "bar", + Valid: true, + }, + }, + }, + { + name: "all valid, equal order relies on name", + input: []*TierInfo{ + { + Name: "baz", + Order: floatPtr(10), + Valid: true, + }, + { + Name: "foo", + Order: floatPtr(10), + Valid: true, + }, + }, + expected: []*TierInfo{ + { + Name: "baz", + Order: floatPtr(10), + Valid: true, + }, + { + Name: "foo", + Order: floatPtr(10), + Valid: true, + }, + }, + }, + } + + insertTierInfos := func(ps *PolicySorter, ti []*TierInfo) { + for _, tierInfo := range ti { + if tierInfo != nil { + tiKey := tierInfoKey{ + Name: tierInfo.Name, + Order: tierInfo.Order, + Valid: tierInfo.Valid, + } + ps.tiers[tierInfo.Name] = tierInfo + ps.sortedTiers.ReplaceOrInsert(tiKey) + } + } + } + + for _, tc := range tests { + ps := NewPolicySorter() + + insertTierInfos(ps, tc.input) + got := ps.Sorted() + + if !reflect.DeepEqual(got, tc.expected) { + t.Errorf("%v: Inserting in input order expected \n %v \n but got \n %v", tc.name, tc.expected, got) + } + + ps = NewPolicySorter() + var reversedInput []*TierInfo + if tc.input != nil { + reversedInput = make([]*TierInfo, len(tc.input)) + for i, v := range tc.input { + reversedInput[len(tc.input)-1-i] = v + } + } + insertTierInfos(ps, reversedInput) + + got = ps.Sorted() + + if !reflect.DeepEqual(got, tc.expected) { + t.Errorf("%v: Inserting in reverse order expected \n %v \n but got \n %v", tc.name, tc.expected, got) + } } } diff --git a/felix/calc/resources_for_test.go b/felix/calc/resources_for_test.go index 0400d3aba2d..bc65b91da10 100644 --- a/felix/calc/resources_for_test.go +++ b/felix/calc/resources_for_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -164,6 +164,13 @@ var localWlEp1DifferentIPs = WorkloadEndpoint{ }, } +var ep1IPs = []string{ + "10.0.0.1/32", // ep1 + "fc00:fe11::1/128", + "10.0.0.2/32", // shared with ep2 + "fc00:fe11::2/128", +} + var localWlEp2 = WorkloadEndpoint{ State: "active", Name: "cali2", diff --git a/felix/calc/rule_convert.go b/felix/calc/rule_convert.go index 52f5d9bba2c..e6e6a044c8e 100644 --- a/felix/calc/rule_convert.go +++ b/felix/calc/rule_convert.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -154,7 +154,7 @@ func parsedRuleToProtoRule(in *ParsedRule) *proto.Rule { protoMatch := &proto.HTTPMatch_PathMatch_Prefix{Prefix: pathMatch.Prefix} paths = append(paths, &proto.HTTPMatch_PathMatch{PathMatch: protoMatch}) } else { - log.Error("Ignoring unknown patch match type", pathMatch) + log.Error("Ignoring unknown path match type", pathMatch) } } if len(paths) > 0 { diff --git a/felix/calc/rule_scanner.go b/felix/calc/rule_scanner.go index 763996750c0..ab7d95a900c 100644 --- a/felix/calc/rule_scanner.go +++ b/felix/calc/rule_scanner.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -90,6 +90,7 @@ type IPSetData struct { // port, set selector to AllSelector. If NamedPortProtocol == ProtocolNone then // this IP set represents a selector only, with no named port component. Selector selector.Selector + // NamedPortProtocol identifies the protocol (TCP or UDP) for a named port IP set. It is // set to ProtocolNone for a selector-only IP set. NamedPortProtocol labelindex.IPSetPortProtocol @@ -421,6 +422,7 @@ func ruleToParsedRule(rule *model.Rule) (parsedRule *ParsedRule, allIPSets []*IP // by the selector above. If we have numeric ports, we can't make the optimization // because we can't filter numeric ports by selector in the same way. var srcSelIPSets, dstSelIPSets []*IPSetData + if len(srcNumericPorts) > 0 || len(srcNamedPorts) == 0 { srcSelIPSets = selectorsToIPSets(srcSel) } @@ -428,6 +430,9 @@ func ruleToParsedRule(rule *model.Rule) (parsedRule *ParsedRule, allIPSets []*IP dstSelIPSets = selectorsToIPSets(dstSel) } + notSrcSelIPSets := selectorsToIPSets(notSrcSels) + notDstSelIPSets := selectorsToIPSets(notDstSels) + // Include any Service IPSet as well. var dstIPPortSets []*IPSetData if rule.DstService != "" { @@ -440,9 +445,6 @@ func ruleToParsedRule(rule *model.Rule) (parsedRule *ParsedRule, allIPSets []*IP srcSelIPSets = append(srcSelIPSets, &IPSetData{Service: svc, ServiceIncludePorts: false}) } - notSrcSelIPSets := selectorsToIPSets(notSrcSels) - notDstSelIPSets := selectorsToIPSets(notDstSels) - parsedRule = &ParsedRule{ Action: rule.Action, @@ -513,6 +515,7 @@ func ruleToParsedRule(rule *model.Rule) (parsedRule *ParsedRule, allIPSets []*IP return } +// Converts a list of named ports to a list of IPSets. func namedPortsToIPSets(namedPorts []string, positiveSelectors []selector.Selector, proto labelindex.IPSetPortProtocol) []*IPSetData { var ipSets []*IPSetData if len(positiveSelectors) > 1 { @@ -534,6 +537,7 @@ func namedPortsToIPSets(namedPorts []string, positiveSelectors []selector.Select return ipSets } +// Converts a list of selectors to a list of IPSets. func selectorsToIPSets(selectors []selector.Selector) []*IPSetData { var ipSets []*IPSetData for _, s := range selectors { @@ -544,6 +548,7 @@ func selectorsToIPSets(selectors []selector.Selector) []*IPSetData { return ipSets } +// Converts a list of IPSets to a list of their unique IDs. func ipSetsToUIDs(ipSets []*IPSetData) []string { var ids []string for _, ipSet := range ipSets { diff --git a/felix/calc/state_test.go b/felix/calc/state_test.go index c76575d667d..386423657f5 100644 --- a/felix/calc/state_test.go +++ b/felix/calc/state_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package calc_test import ( "fmt" "reflect" + "strings" "github.com/sirupsen/logrus" @@ -48,6 +49,8 @@ type State struct { ExpectedPreDNATEndpointPolicyOrder map[string][]mock.TierInfo ExpectedHostMetadataV4V6 map[string]proto.HostMetadataV4V6Update ExpectedNumberOfALPPolicies int + ExpectedNumberOfTiers int + ExpectedNumberOfPolicies int ExpectedEncapsulation proto.Encapsulation } @@ -74,6 +77,8 @@ func NewState() State { ExpectedUntrackedEndpointPolicyOrder: make(map[string][]mock.TierInfo), ExpectedPreDNATEndpointPolicyOrder: make(map[string][]mock.TierInfo), ExpectedHostMetadataV4V6: make(map[string]proto.HostMetadataV4V6Update), + ExpectedNumberOfPolicies: -1, + ExpectedNumberOfTiers: -1, } } @@ -96,6 +101,7 @@ func (s State) Copy() State { for k, v := range s.ExpectedHostMetadataV4V6 { cpy.ExpectedHostMetadataV4V6[k] = v } + cpy.ExpectedPolicyIDs = s.ExpectedPolicyIDs.Copy() cpy.ExpectedUntrackedPolicyIDs = s.ExpectedUntrackedPolicyIDs.Copy() cpy.ExpectedPreDNATPolicyIDs = s.ExpectedPreDNATPolicyIDs.Copy() @@ -105,9 +111,12 @@ func (s State) Copy() State { cpy.ExpectedWireguardEndpoints = s.ExpectedWireguardEndpoints.Copy() cpy.ExpectedWireguardV6Endpoints = s.ExpectedWireguardV6Endpoints.Copy() cpy.ExpectedNumberOfALPPolicies = s.ExpectedNumberOfALPPolicies + cpy.ExpectedNumberOfTiers = s.ExpectedNumberOfTiers + cpy.ExpectedNumberOfPolicies = s.ExpectedNumberOfPolicies cpy.ExpectedEncapsulation = s.ExpectedEncapsulation cpy.Name = s.Name + return cpy } @@ -121,20 +130,23 @@ func (s State) withKVUpdates(kvs ...model.KVPair) (newState State) { newState.DatastoreState = make([]model.KVPair, 0, len(kvs)+len(s.DatastoreState)) // Make a set containing the new keys. newKeys := make(map[string]bool) - for _, kv := range kvs { - path, err := model.KeyToDefaultPath(kv.Key) - if err != nil { - logrus.WithField("key", kv.Key).Panic("Unable to convert key to default path") + + for i, kv := range kvs { + if k, ok := kv.Key.(model.PolicyKey); ok { + if k.Tier == "" { + k.Tier = "default" + kv.Key = k + kvs[i] = kv + } } - newKeys[path] = true + } + + for _, kv := range kvs { + newKeys[kvToPath(kv)] = true } // Copy across the old KVs, skipping ones that are in the updates set. for _, kv := range s.DatastoreState { - path, err := model.KeyToDefaultPath(kv.Key) - if err != nil { - logrus.WithField("key", kv.Key).Panic("Unable to convert key to default path") - } - if newKeys[path] { + if newKeys[kvToPath(kv)] { continue } newState.DatastoreState = append(newState.DatastoreState, kv) @@ -157,7 +169,7 @@ func (s State) withIPSet(name string, members []string) (newState State) { } else { memSet := set.New[string]() for _, ip := range members { - memSet.Add(ip) + memSet.Add(strings.ToLower(ip)) } newState.ExpectedIPSets[name] = memSet } @@ -203,6 +215,18 @@ func (s State) withTotalALPPolicies(count int) (newState State) { return newState } +func (s State) withTotalTiers(count int) (newState State) { + newState = s.Copy() + newState.ExpectedNumberOfTiers = count + return newState +} + +func (s State) withTotalActivePolicies(count int) (newState State) { + newState = s.Copy() + newState.ExpectedNumberOfPolicies = count + return newState +} + func (s State) withUntrackedPolicies(ids ...proto.PolicyID) (newState State) { newState = s.Copy() newState.ExpectedUntrackedPolicyIDs = set.New[proto.PolicyID]() @@ -327,8 +351,20 @@ func (s State) KVDeltas(prev State) []api.Update { return deltas } +func (s State) NumTiers() int { + if s.ExpectedNumberOfTiers == -1 { + return s.ActiveKeys(model.TierKey{}).Len() + } else { + return s.ExpectedNumberOfTiers + } +} + func (s State) NumPolicies() int { - return s.ActiveKeys(model.PolicyKey{}).Len() + if s.ExpectedNumberOfPolicies == -1 { + return s.ActiveKeys(model.PolicyKey{}).Len() + } else { + return s.ExpectedNumberOfPolicies + } } func (s State) NumProfileRules() int { diff --git a/felix/calc/states_for_test.go b/felix/calc/states_for_test.go index fe4bacc4c79..ec9b9619f14 100644 --- a/felix/calc/states_for_test.go +++ b/felix/calc/states_for_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,6 +29,12 @@ import ( "github.com/projectcalico/calico/felix/proto" ) +// Canned tiers/policies. + +var tier1_order20 = Tier{ + Order: &order20, +} + // Pre-defined datastore states. Each State object wraps up the complete state // of the datastore as well as the expected state of the dataplane. The state // of the dataplane *should* depend only on the current datastore state, not on @@ -36,6 +42,9 @@ import ( // from any state to any other state (by feeding in the corresponding // datastore updates) and then assert that the dataplane matches the resulting // state. +// +// Notice that most of these pre-defined states are compounded. A small test +// might prefer to start with a simpler state instead. // empty is the base state, with nothing in the datastore or dataplane. var empty = NewState().withName("") @@ -47,11 +56,12 @@ var initialisedStore = empty.withKVUpdates( ).withName("") // withPolicy adds a tier and policy containing selectors for all and b=="b" -var pol1KVPair = KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20} -var pol1KVPairAlways = KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_always} -var pol1KVPairOnDemand = KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_ondemand} +var pol1KVPair = KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20} +var pol1KVPairAlways = KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_always} +var pol1KVPairOnDemand = KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_ondemand} var withPolicy = initialisedStore.withKVUpdates( + KVPair{Key: TierKey{Name: "default"}, Value: &tier1_order20}, pol1KVPair, ).withName("with policy") @@ -63,22 +73,22 @@ var withPolicyAlways = initialisedStore.withKVUpdates( // withPolicyIngressOnly adds a tier and ingress policy containing selectors for all var withPolicyIngressOnly = initialisedStore.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_ingress_only}, + KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_ingress_only}, ).withName("with ingress-only policy") // withPolicyEgressOnly adds a tier and egress policy containing selectors for b=="b" var withPolicyEgressOnly = initialisedStore.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_egress_only}, + KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_egress_only}, ).withName("with egress-only policy") // withUntrackedPolicy adds a tier and policy containing selectors for all and b=="b" var withUntrackedPolicy = initialisedStore.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_untracked}, + KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_untracked}, ).withName("with untracked policy") // withPreDNATPolicy adds a tier and policy containing selectors for all and a=="a" var withPreDNATPolicy = initialisedStore.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pre-dnat-pol-1"}, Value: &policy1_order20_pre_dnat}, + KVPair{Key: PolicyKey{Name: "pre-dnat-pol-1", Tier: "default"}, Value: &policy1_order20_pre_dnat}, ).withName("with pre-DNAT policy") // withHttpMethodPolicy adds a policy containing http method selector. @@ -177,6 +187,290 @@ var localEp1WithPolicy = withPolicy.withKVUpdates( routelocalWlV6ColonTwo, ).withName("ep1 local, policy") +// withPolicyAndTier adds a tier and policy containing selectors for all and b=="b" +var withPolicyAndTier = initialisedStore.withKVUpdates( + KVPair{Key: TierKey{Name: "tier-1"}, Value: &tier1_order20}, + KVPair{Key: PolicyKey{Tier: "tier-1", Name: "pol-1"}, Value: &policy1_order20}, +).withName("with policy") + +// localEp1WithPolicyAndTier adds a local endpoint to the mix. It matches all and b=="b". +var localEp1WithPolicyAndTier = withPolicyAndTier.withKVUpdates( + KVPair{Key: localWlEpKey1, Value: &localWlEp1}, +).withIPSet(allSelectorId, []string{ + "10.0.0.1/32", // ep1 + "fc00:fe11::1/128", + "10.0.0.2/32", // ep1 and ep2 + "fc00:fe11::2/128", +}).withIPSet(bEqBSelectorId, []string{ + "10.0.0.1/32", + "fc00:fe11::1/128", + "10.0.0.2/32", + "fc00:fe11::2/128", +}).withActivePolicies( + proto.PolicyID{Tier: "tier-1", Name: "pol-1"}, +).withActiveProfiles( + proto.ProfileID{Name: "prof-1"}, + proto.ProfileID{Name: "prof-2"}, + proto.ProfileID{Name: "prof-missing"}, +).withEndpoint( + localWlEp1Id, + []mock.TierInfo{ + { + Name: "tier-1", + IngressPolicyNames: []string{"pol-1"}, + EgressPolicyNames: []string{"pol-1"}, + }, + }, +).withRoutes( + // Routes for the local WEPs. + routelocalWlTenDotOne, + routelocalWlTenDotTwo, + routelocalWlV6ColonOne, + routelocalWlV6ColonTwo, +).withName("ep1 local, policy with non-default tier") + +// localEp2WithPolicyAndTier adds a different endpoint that doesn't match b=="b". +// This tests an empty IP set. +var localEp2WithPolicyAndTier = withPolicyAndTier.withKVUpdates( + KVPair{Key: localWlEpKey2, Value: &localWlEp2}, +).withIPSet(allSelectorId, []string{ + "10.0.0.2/32", // ep1 and ep2 + "fc00:fe11::2/128", + "10.0.0.3/32", // ep2 + "fc00:fe11::3/128", +}).withIPSet( + bEqBSelectorId, []string{}, +).withActivePolicies( + proto.PolicyID{Tier: "tier-1", Name: "pol-1"}, +).withActiveProfiles( + proto.ProfileID{Name: "prof-2"}, + proto.ProfileID{Name: "prof-3"}, +).withEndpoint( + localWlEp2Id, + []mock.TierInfo{ + { + Name: "tier-1", + IngressPolicyNames: []string{"pol-1"}, + EgressPolicyNames: []string{"pol-1"}, + }, + }, +).withRoutes( + // Routes for the local WEPs. + routelocalWlTenDotTwo, + routelocalWlTenDotThree, + routelocalWlV6ColonTwo, + routelocalWlV6ColonThree, +).withName("ep2 local, policy") + +// Policy ordering tests. We keep the names of the policies the same but we +// change their orders to check that order trumps name. +var commLocalEp1WithOneTierPolicy123 = commercialPolicyOrderState( + [3]float64{order10, order20, order30}, + [3]string{"pol-1", "pol-2", "pol-3"}, +) + +var commLocalEp1WithOneTierPolicy321 = commercialPolicyOrderState( + [3]float64{order30, order20, order10}, + [3]string{"pol-3", "pol-2", "pol-1"}, +) + +var commLocalEp1WithOneTierPolicyAlpha = commercialPolicyOrderState( + [3]float64{order10, order10, order10}, + [3]string{"pol-1", "pol-2", "pol-3"}, +) + +func commercialPolicyOrderState(policyOrders [3]float64, expectedOrder [3]string) State { + policies := [3]Policy{} + for i := range policies { + policies[i] = Policy{ + Order: &policyOrders[i], + Selector: "a == 'a'", + InboundRules: []Rule{{SrcSelector: allSelector}}, + OutboundRules: []Rule{{SrcSelector: bEpBSelector}}, + } + } + state := initialisedStore.withKVUpdates( + KVPair{Key: localWlEpKey1, Value: &localWlEp1}, + KVPair{Key: TierKey{Name: "tier-1"}, Value: &tier1_order20}, + KVPair{Key: PolicyKey{Tier: "tier-1", Name: "pol-1"}, Value: &policies[0]}, + KVPair{Key: PolicyKey{Tier: "tier-1", Name: "pol-2"}, Value: &policies[1]}, + KVPair{Key: PolicyKey{Tier: "tier-1", Name: "pol-3"}, Value: &policies[2]}, + ).withIPSet(allSelectorId, []string{ + "10.0.0.1/32", // ep1 + "fc00:fe11::1/128", + "10.0.0.2/32", // ep1 and ep2 + "fc00:fe11::2/128", + }).withIPSet(bEqBSelectorId, []string{ + "10.0.0.1/32", + "fc00:fe11::1/128", + "10.0.0.2/32", + "fc00:fe11::2/128", + }).withActivePolicies( + proto.PolicyID{Tier: "tier-1", Name: "pol-1"}, + proto.PolicyID{Tier: "tier-1", Name: "pol-2"}, + proto.PolicyID{Tier: "tier-1", Name: "pol-3"}, + ).withActiveProfiles( + proto.ProfileID{Name: "prof-1"}, + proto.ProfileID{Name: "prof-2"}, + proto.ProfileID{Name: "prof-missing"}, + ).withEndpoint( + localWlEp1Id, + []mock.TierInfo{ + { + Name: "tier-1", + IngressPolicyNames: expectedOrder[:], + EgressPolicyNames: expectedOrder[:], + }, + }, + ).withRoutes( + // Routes for the local WEPs. + routelocalWlTenDotOne, + routelocalWlTenDotTwo, + routelocalWlV6ColonOne, + routelocalWlV6ColonTwo, + ).withName(fmt.Sprintf("ep1 local, 1 tier, policies %v", expectedOrder[:])) + return state +} + +// Tier ordering tests. We keep the names of the tiers constant but adjust +// their orders. +var localEp1WithTiers123 = tierOrderState( + [3]float64{order10, order20, order30}, + [3]string{"tier-1", "tier-2", "tier-3"}, +) + +var localEp1WithTiers321 = tierOrderState( + [3]float64{order30, order20, order10}, + [3]string{"tier-3", "tier-2", "tier-1"}, +) + +// These tests use the same order for each tier, checking that the name is +// used as a tie breaker. +var localEp1WithTiersAlpha = tierOrderState( + [3]float64{order10, order10, order10}, + [3]string{"tier-1", "tier-2", "tier-3"}, +) + +var localEp1WithTiersAlpha2 = tierOrderState( + [3]float64{order20, order20, order20}, + [3]string{"tier-1", "tier-2", "tier-3"}, +) + +var localEp1WithTiersAlpha3 = tierOrderState( + [3]float64{order20, order20, order10}, + [3]string{"tier-3", "tier-1", "tier-2"}, +) + +func tierOrderState(tierOrders [3]float64, expectedOrder [3]string) State { + tiers := [3]Tier{} + for i := range tiers { + tiers[i] = Tier{ + Order: &tierOrders[i], + } + } + state := initialisedStore.withKVUpdates( + KVPair{Key: localWlEpKey1, Value: &localWlEp1}, + KVPair{Key: TierKey{Name: "tier-1"}, Value: &tiers[0]}, + KVPair{Key: PolicyKey{Tier: "tier-1", Name: "tier-1-pol"}, Value: &policy1_order20}, + KVPair{Key: TierKey{Name: "tier-2"}, Value: &tiers[1]}, + KVPair{Key: PolicyKey{Tier: "tier-2", Name: "tier-2-pol"}, Value: &policy1_order20}, + KVPair{Key: TierKey{Name: "tier-3"}, Value: &tiers[2]}, + KVPair{Key: PolicyKey{Tier: "tier-3", Name: "tier-3-pol"}, Value: &policy1_order20}, + ).withIPSet( + allSelectorId, ep1IPs, + ).withIPSet( + bEqBSelectorId, ep1IPs, + ).withActivePolicies( + proto.PolicyID{Tier: "tier-1", Name: "tier-1-pol"}, + proto.PolicyID{Tier: "tier-2", Name: "tier-2-pol"}, + proto.PolicyID{Tier: "tier-3", Name: "tier-3-pol"}, + ).withActiveProfiles( + proto.ProfileID{Name: "prof-1"}, + proto.ProfileID{Name: "prof-2"}, + proto.ProfileID{Name: "prof-missing"}, + ).withEndpoint( + localWlEp1Id, + []mock.TierInfo{ + { + Name: expectedOrder[0], + IngressPolicyNames: []string{expectedOrder[0] + "-pol"}, + EgressPolicyNames: []string{expectedOrder[0] + "-pol"}, + }, + { + Name: expectedOrder[1], + IngressPolicyNames: []string{expectedOrder[1] + "-pol"}, + EgressPolicyNames: []string{expectedOrder[1] + "-pol"}, + }, + { + Name: expectedOrder[2], + IngressPolicyNames: []string{expectedOrder[2] + "-pol"}, + EgressPolicyNames: []string{expectedOrder[2] + "-pol"}, + }, + }, + ).withRoutes( + // Routes for the local WEPs. + routelocalWlTenDotOne, + routelocalWlTenDotTwo, + routelocalWlV6ColonOne, + routelocalWlV6ColonTwo, + ).withName(fmt.Sprintf("tier-order-state%v", expectedOrder[:])) + return state +} + +// localEpsWithPolicyAndTier contains both of the above endpoints, which have some +// overlapping IPs. When we sequence this with the states above, we test +// overlapping IP addition and removal. +var localEpsWithPolicyAndTier = withPolicyAndTier.withKVUpdates( + // Two local endpoints with overlapping IPs. + KVPair{Key: localWlEpKey1, Value: &localWlEp1}, + KVPair{Key: localWlEpKey2, Value: &localWlEp2}, +).withIPSet(allSelectorId, []string{ + "10.0.0.1/32", // ep1 + "fc00:fe11::1/128", + "10.0.0.2/32", // ep1 and ep2 + "fc00:fe11::2/128", + "10.0.0.3/32", // ep2 + "fc00:fe11::3/128", +}).withIPSet(bEqBSelectorId, []string{ + "10.0.0.1/32", + "fc00:fe11::1/128", + "10.0.0.2/32", + "fc00:fe11::2/128", +}).withActivePolicies( + proto.PolicyID{Tier: "tier-1", Name: "pol-1"}, +).withActiveProfiles( + proto.ProfileID{Name: "prof-1"}, + proto.ProfileID{Name: "prof-2"}, + proto.ProfileID{Name: "prof-3"}, + proto.ProfileID{Name: "prof-missing"}, +).withEndpoint( + localWlEp1Id, + []mock.TierInfo{ + { + Name: "tier-1", + IngressPolicyNames: []string{"pol-1"}, + EgressPolicyNames: []string{"pol-1"}, + }, + }, +).withEndpoint( + localWlEp2Id, + []mock.TierInfo{ + { + Name: "tier-1", + IngressPolicyNames: []string{"pol-1"}, + EgressPolicyNames: []string{"pol-1"}, + }, + }, +).withRoutes( + // Routes for the local WEPs. + routelocalWlTenDotOne, + routelocalWlTenDotTwo, + routelocalWlTenDotThree, + routelocalWlV6ColonOne, + routelocalWlV6ColonTwo, + routelocalWlV6ColonThree, +).withName("2 local, overlapping IPs & a policy") + var localEp1WithPolicyAlways = localEp1WithPolicy.withKVUpdates( pol1KVPairAlways, ).withName("ep1 local, always policy") @@ -187,7 +481,7 @@ var localEp1WithPolicyOnDemand = localEp1WithPolicy.withKVUpdates( // localEp1WithNamedPortPolicy as above but with named port in the policy. var localEp1WithNamedPortPolicy = localEp1WithPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport}, ).withIPSet(namedPortAllTCPID, []string{ "10.0.0.1,tcp:8080", "10.0.0.2,tcp:8080", @@ -198,7 +492,7 @@ var localEp1WithNamedPortPolicy = localEp1WithPolicy.withKVUpdates( // localEp1WithNamedPortPolicy as above but with negated named port in the policy. var localEp1WithNegatedNamedPortPolicy = empty.withKVUpdates( KVPair{Key: localWlEpKey1, Value: &localWlEp1}, - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_selector_and_negated_named_port_tcpport}, + KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_with_selector_and_negated_named_port_tcpport}, ).withIPSet(namedPortAllLessFoobarTCPID, []string{ "10.0.0.1,tcp:8080", "10.0.0.2,tcp:8080", @@ -235,7 +529,7 @@ var localEp1WithNegatedNamedPortPolicy = empty.withKVUpdates( // As above but using the destination fields in the policy instead of source. var localEp1WithNegatedNamedPortPolicyDest = localEp1WithNegatedNamedPortPolicy.withKVUpdates( KVPair{ - Key: PolicyKey{Name: "pol-1"}, + Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policy1_order20_with_selector_and_negated_named_port_tcpport_dest, }, ).withName("ep1 local, negated named port policy in destination fields") @@ -243,7 +537,7 @@ var localEp1WithNegatedNamedPortPolicyDest = localEp1WithNegatedNamedPortPolicy. // A host endpoint with a named port var localHostEp1WithNamedPortPolicy = empty.withKVUpdates( KVPair{Key: hostEpWithNameKey, Value: &hostEpWithNamedPorts}, - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport}, ).withIPSet(namedPortAllTCPID, []string{ "10.0.0.1,tcp:8080", "10.0.0.2,tcp:8080", @@ -267,12 +561,12 @@ var localHostEp1WithNamedPortPolicy = empty.withKVUpdates( // As above but with no selector in the rules. var localEp1WithNamedPortPolicyNoSelector = localEp1WithNamedPortPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_named_port_tcpport}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_named_port_tcpport}, ).withName("ep1 local, named port only") // As above but with negated named port. var localEp1WithNegatedNamedPortPolicyNoSelector = localEp1WithNamedPortPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_named_port_tcpport_negated}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_named_port_tcpport_negated}, ).withName("ep1 local, negated named port only") // localEp1WithIngressPolicy is as above except ingress policy only. @@ -304,7 +598,7 @@ var localEp1WithIngressPolicy = withPolicyIngressOnly.withKVUpdates( // localEp1WithNamedPortPolicy as above but with UDP named port in the policy. var localEp1WithNamedPortPolicyUDP = localEp1WithPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_udpport}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_udpport}, ).withIPSet(namedPortAllUDPID, []string{ "10.0.0.1,udp:9091", "10.0.0.2,udp:9091", @@ -431,7 +725,7 @@ var hostEp1WithPreDNATPolicy = withPreDNATPolicy.withKVUpdates( ).withName("host ep1, pre-DNAT policy") var hostEp1WithTrackedAndUntrackedPolicy = hostEp1WithUntrackedPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-2"}, Value: &policy1_order20}, + KVPair{Key: PolicyKey{Name: "pol-2", Tier: "default"}, Value: &policy1_order20}, ).withActivePolicies( proto.PolicyID{Tier: "default", Name: "pol-1"}, proto.PolicyID{Tier: "default", Name: "pol-2"}, @@ -494,9 +788,9 @@ func policyOrderState(policyOrders [3]float64, expectedOrder [3]string) State { } state := initialisedStore.withKVUpdates( KVPair{Key: localWlEpKey1, Value: &localWlEp1}, - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policies[0]}, - KVPair{Key: PolicyKey{Name: "pol-2"}, Value: &policies[1]}, - KVPair{Key: PolicyKey{Name: "pol-3"}, Value: &policies[2]}, + KVPair{Key: PolicyKey{Name: "pol-1", Tier: "default"}, Value: &policies[0]}, + KVPair{Key: PolicyKey{Name: "pol-2", Tier: "default"}, Value: &policies[1]}, + KVPair{Key: PolicyKey{Name: "pol-3", Tier: "default"}, Value: &policies[2]}, ).withIPSet(allSelectorId, []string{ "10.0.0.1/32", // ep1 "fc00:fe11::1/128", @@ -606,7 +900,7 @@ var localEpsWithPolicy = withPolicy.withKVUpdates( ).withName("2 local, overlapping IPs & a policy") var localEpsWithNamedPortsPolicy = localEpsWithPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport}, ).withIPSet( allSelectorId, nil, ).withIPSet(namedPortAllTCPID, []string{ @@ -619,7 +913,7 @@ var localEpsWithNamedPortsPolicy = localEpsWithPolicy.withKVUpdates( }).withName("2 local, overlapping IPs & a named port policy") var localEpsWithNamedPortsPolicyTCPPort2 = localEpsWithPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport2}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_selector_and_named_port_tcpport2}, ).withIPSet( allSelectorId, nil, ).withIPSet(namedPortAllTCP2ID, []string{ @@ -638,7 +932,7 @@ var localEpsWithNamedPortsPolicyTCPPort2 = localEpsWithPolicy.withKVUpdates( // localEpsWithMismatchedNamedPortsPolicy contains a policy that has named port matches where the // rule has a protocol that doesn't match that in the named port definitions in the endpoint. var localEpsWithMismatchedNamedPortsPolicy = localEpsWithPolicy.withKVUpdates( - KVPair{Key: PolicyKey{Name: "pol-1"}, Value: &policy1_order20_with_named_port_mismatched_protocol}, + KVPair{Key: PolicyKey{Tier: "default", Name: "pol-1"}, Value: &policy1_order20_with_named_port_mismatched_protocol}, ).withIPSet( allSelectorId, nil, ).withIPSet( @@ -680,7 +974,7 @@ var localEpsWithOverlappingIPsAndInheritedLabels = empty.withKVUpdates( // Building on the above, we add a policy to match on the inherited label, which should produce // a named port. var localEpsAndNamedPortPolicyMatchingInheritedLabelOnEP1 = localEpsWithOverlappingIPsAndInheritedLabels.withKVUpdates( - KVPair{Key: PolicyKey{Name: "inherit-pol"}, Value: &policy_with_named_port_inherit}, + KVPair{Key: PolicyKey{Tier: "default", Name: "inherit-pol"}, Value: &policy_with_named_port_inherit}, ).withActivePolicies( proto.PolicyID{Tier: "default", Name: "inherit-pol"}, ).withEndpoint( diff --git a/felix/calc/stats_collector.go b/felix/calc/stats_collector.go index 0438ab7d95e..c76262c7560 100644 --- a/felix/calc/stats_collector.go +++ b/felix/calc/stats_collector.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,6 +37,10 @@ var ( Name: "felix_cluster_num_workload_endpoints", Help: "Total number of workload endpoints cluster-wide.", }) + gaugeClusNumTiers = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "felix_cluster_num_tiers", + Help: "Total number of tiers cluster-wide.", + }) gaugeClusNumPolicies = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "felix_cluster_num_policies", Help: "Total number of policies cluster-wide.", @@ -51,6 +55,7 @@ func init() { prometheus.MustRegister(gaugeClusNumHosts) prometheus.MustRegister(gaugeClusNumHostEndpoints) prometheus.MustRegister(gaugeClusNumWorkloadEndpoints) + prometheus.MustRegister(gaugeClusNumTiers) prometheus.MustRegister(gaugeClusNumPolicies) prometheus.MustRegister(gaugeClusNumProfiles) } @@ -59,6 +64,7 @@ type StatsCollector struct { keyCountByHost map[string]int numWorkloadEndpoints int numHostEndpoints int + numTiers int numPolicies int numProfiles int numALPPolicies int @@ -73,6 +79,7 @@ type StatsUpdate struct { NumHosts int NumWorkloadEndpoints int NumHostEndpoints int + NumTiers int NumPolicies int NumProfiles int NumALPPolicies int @@ -155,16 +162,18 @@ func (s *StatsCollector) OnUpdate(update api.Update) (filterOut bool) { return } -func (s *StatsCollector) UpdatePolicyCounts(numPolicies, numProfiles, numALPPolicies int) { - if numPolicies == s.numPolicies && numProfiles == s.numProfiles && numALPPolicies == s.numALPPolicies { +func (s *StatsCollector) UpdatePolicyCounts(numTiers, numPolicies, numProfiles, numALPPolicies int) { + if numTiers == s.numTiers && numPolicies == s.numPolicies && numProfiles == s.numProfiles && numALPPolicies == s.numALPPolicies { return } log.WithFields(log.Fields{ + "numTiers": numTiers, "numPolicies": numPolicies, "numProfiles": numProfiles, "numALPPolicies": numALPPolicies, - }).Debug("Number of policies/profiles changed") + }).Debug("Number of tiers/policies/profiles changed") + s.numTiers = numTiers s.numPolicies = numPolicies s.numProfiles = numProfiles s.numALPPolicies = numALPPolicies @@ -177,6 +186,7 @@ func (s *StatsCollector) sendUpdate() { NumHosts: len(s.keyCountByHost), NumHostEndpoints: s.numHostEndpoints, NumWorkloadEndpoints: s.numWorkloadEndpoints, + NumTiers: s.numTiers, NumPolicies: s.numPolicies, NumProfiles: s.numProfiles, NumALPPolicies: s.numALPPolicies, @@ -184,6 +194,7 @@ func (s *StatsCollector) sendUpdate() { gaugeClusNumHosts.Set(float64(len(s.keyCountByHost))) gaugeClusNumWorkloadEndpoints.Set(float64(s.numWorkloadEndpoints)) gaugeClusNumHostEndpoints.Set(float64(s.numHostEndpoints)) + gaugeClusNumTiers.Set(float64(s.numTiers)) gaugeClusNumPolicies.Set(float64(s.numPolicies)) gaugeClusNumProfiles.Set(float64(s.numProfiles)) if s.inSync && s.lastUpdate != update { diff --git a/felix/calc/stats_collector_test.go b/felix/calc/stats_collector_test.go index a8a9976fb55..f5bd4204186 100644 --- a/felix/calc/stats_collector_test.go +++ b/felix/calc/stats_collector_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ var _ = Describe("Stats collector", func() { Expect(lastStatsUpdate).To(BeNil()) }) It("should do nothing on policy count update", func() { - sc.UpdatePolicyCounts(10, 10, 10) + sc.UpdatePolicyCounts(5, 10, 10, 10) Expect(lastStatsUpdate).To(BeNil()) }) }) @@ -96,19 +96,20 @@ var _ = Describe("Stats collector", func() { })) }) It("should count a policy", func() { - sc.UpdatePolicyCounts(1, 0, 0) + sc.UpdatePolicyCounts(1, 1, 0, 0) Expect(*lastStatsUpdate).To(Equal(StatsUpdate{ + NumTiers: 1, NumPolicies: 1, })) }) It("should count a profile", func() { - sc.UpdatePolicyCounts(0, 1, 0) + sc.UpdatePolicyCounts(0, 0, 1, 0) Expect(*lastStatsUpdate).To(Equal(StatsUpdate{ NumProfiles: 1, })) }) It("should count a ALP policy", func() { - sc.UpdatePolicyCounts(0, 0, 1) + sc.UpdatePolicyCounts(0, 0, 0, 1) Expect(*lastStatsUpdate).To(Equal(StatsUpdate{ NumALPPolicies: 1, })) diff --git a/felix/check-licenses/.gitignore b/felix/check-licenses/.gitignore deleted file mode 100644 index 4e8560ec2eb..00000000000 --- a/felix/check-licenses/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dependency-licenses.txt diff --git a/felix/check-licenses/check_licenses.go b/felix/check-licenses/check_licenses.go deleted file mode 100644 index fb0de5efb59..00000000000 --- a/felix/check-licenses/check_licenses.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) 2017, 2019 Tigera, Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "bufio" - "os" - "regexp" - "strings" - - log "github.com/sirupsen/logrus" - - "github.com/projectcalico/calico/felix/logutils" - "github.com/projectcalico/calico/libcalico-go/lib/set" -) - -var ( - approvedLicenses = set.From( - "Apache License 2.0", - "MIT License", - "ISC License", - "BSD 3-clause \"New\" or \"Revised\" License", - ) - approvedPkgs = set.FromArray([]pkgInfo{ - // These packages are licensed under the LGPL, which is normally viral and hence - // incompatible with our licensing! However, they include the linking exception, - // allowing us to distribute a binary based on them as long as we don't modify them. - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/juju/ratelimit", - license: "GNU Lesser General Public License v3.0 (94%)"}, - - // Variants on MIT/BSD; files tend to include updated copyright statement. - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/PuerkitoBio/urlesc", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/beorn7/perks/quantile", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/gobuffalo/gogen/goimports", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/gogo/protobuf", - license: "BSD 3-clause \"New\" or \"Revised\" License (90%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/golang/protobuf", - license: "BSD 3-clause \"New\" or \"Revised\" License (92%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/golang/protobuf/proto", - license: "BSD 3-clause \"New\" or \"Revised\" License (92%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/gregjones/httpcache/diskcache", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/howeyc/gopass", - license: "ISC License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/karrick/godirwalk", - license: "BSD 2-clause \"Simplified\" License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/davecgh/go-spew/spew", - license: "ISC License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/dgrijalva/jwt-go", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/imdario/mergo", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/kardianos/osext", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/kelseyhightower/envconfig", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/mailru/easyjson", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/pborman/uuid", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/peterbourgon/diskv", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/pkg/errors", - license: "BSD 2-clause \"Simplified\" License"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/rogpeppe/go-internal", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/satori/go.uuid", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/spf13/pflag", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/google.golang.org/grpc", - license: "BSD 3-clause \"New\" or \"Revised\" License (97%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/gopkg.in/inf.v0", - license: "BSD 3-clause \"New\" or \"Revised\" License (97%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/dustin/go-humanize", - license: "MIT License (96%)"}, - - // Mixed license, Apache and some files under BSD-like. - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/ghodss/yaml", - license: "? (BSD 3-clause \"New\" or \"Revised\" License, 83%)"}, - - // Apache license with copyright statement in file. - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/Azure/go-autorest/autorest", - license: "Apache License 2.0 (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/gophercloud/gophercloud", - license: "Apache License 2.0 (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/vishvananda/netlink/nl", - license: "Apache License 2.0 (96%)"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/vishvananda/netns", - license: "Apache License 2.0 (96%)"}, - - // Mozilla Public License. Note, would prohibit us from ever releasing our code - // under a *GPL license (if we wanted to do that). - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/hashicorp/golang-lru/simplelru", - license: "Mozilla Public License 2.0"}, - {pkgName: "github.com/projectcalico/calico/felix/vendor/github.com/hashicorp/go-version", - license: "Mozilla Public License 2.0"}, - // Not detected properly - But it's apache license - https://github.com/go-yaml/yaml/blob/v2.2.1/LICENSE - {pkgName: "github.com/projectcalico/calico/felix/vendor/gopkg.in/yaml.v2", - license: "? (The Unlicense, 35%)"}, - }) - approvedPrefixes = []string{ - // Standard golang BSD-like license. - "github.com/projectcalico/calico/felix/vendor/golang.org/x/", - } -) - -func main() { - logutils.ConfigureEarlyLogging() - - wd, _ := os.Getwd() - log.WithField("PWD", wd).Info("Current directory") - file, err := os.Open("check-licenses/dependency-licenses.txt") // For read access. - if err != nil { - log.WithError(err).Panic("Failed to open licenses file") - } - scanner := bufio.NewScanner(file) - lineRE := regexp.MustCompile(`^(\S+)\s+(\S.*)$`) - badPackages := []pkgInfo{} -lineLoop: - for scanner.Scan() { - line := scanner.Text() - logCxt := log.WithField("line", line) - submatches := lineRE.FindStringSubmatch(line) - if len(submatches) != 3 { - logCxt.Panic("Expected line to match regex") - } - pkgName := submatches[1] - license := submatches[2] - logCxt = logCxt.WithFields(log.Fields{ - "pkgName": pkgName, - "license": license, - }) - logCxt.Debug("Found package") - pkgInfo := pkgInfo{ - pkgName: pkgName, - license: license, - } - if strings.HasPrefix(pkgName, "github.com/projectcalico/calico/felix/vendor/github.com/projectcalico/") || - (strings.HasPrefix(pkgName, "github.com/projectcalico/calico/") && - !strings.Contains(pkgName, "vendor")) { - logCxt.Info("One of our packages") - continue - } - if approvedLicenses.Contains(license) { - logCxt.Info("License is approved") - continue - } - if approvedPkgs.Contains(pkgInfo) { - logCxt.Info("Package is approved") - continue - } - for _, prefix := range approvedPrefixes { - if strings.HasPrefix(pkgName, prefix) { - logCxt.WithField("prefix", prefix).Info("Package prefix is approved") - continue lineLoop - } - } - logCxt.Error("License not approved") - badPackages = append(badPackages, pkgInfo) - } - - if len(badPackages) > 0 { - log.Error("Found bad licenses") - for _, pkg := range badPackages { - log.Errorf("\n\nNon-approved license:\n Package: %v\n License: %v\n", pkg.pkgName, pkg.license) - } - log.Info("") - os.Exit(1) - } -} - -type pkgInfo struct { - pkgName string - license string -} diff --git a/felix/cmd/calico-bpf/commands/policy_debug.go b/felix/cmd/calico-bpf/commands/policy_debug.go index d9b77729ab7..874703b2e04 100644 --- a/felix/cmd/calico-bpf/commands/policy_debug.go +++ b/felix/cmd/calico-bpf/commands/policy_debug.go @@ -153,7 +153,7 @@ func dumpPolicyInfo(cmd *cobra.Command, iface string, h hook.Hook, m counters.Po if strings.Contains(comment, "Rule MatchID") { matchId := getRuleMatchID(comment) cmd.Printf("// count = %d\n", m[matchId]) - } else if verboseFlagSet || strings.Contains(comment, "Start of policy") || strings.Contains(comment, "Start of rule") { + } else if verboseFlagSet || strings.Contains(comment, "Start of policy") || strings.Contains(comment, "Start of rule") || strings.Contains(comment, "IPSets") { cmd.Printf("// %s\n", comment) } } diff --git a/felix/config/config_params.go b/felix/config/config_params.go index da529f3511f..c5e8b72d73c 100644 --- a/felix/config/config_params.go +++ b/felix/config/config_params.go @@ -204,6 +204,7 @@ type Config struct { BPFForceTrackPacketsFromIfaces []string `config:"iface-filter-slice;docker+"` BPFDisableGROForIfaces *regexp.Regexp `config:"regexp;"` BPFExcludeCIDRsFromNAT []string `config:"cidr-list;;"` + BPFRedirectToPeer string `config:"oneof(Disabled,Enabled,L2Only);L2Only;non-zero"` // DebugBPFCgroupV2 controls the cgroup v2 path that we apply the connect-time load balancer to. Most distros // are configured for cgroup v1, which prevents all but the root cgroup v2 from working so this is only useful @@ -418,6 +419,18 @@ type Config struct { // Encapsulation information calculated from IP Pools and FelixConfiguration (VXLANEnabled and IpInIpEnabled) Encapsulation Encapsulation + // NftablesRefreshInterval controls the interval at which Felix periodically refreshes the nftables rules. [Default: 180s] + NftablesRefreshInterval time.Duration `config:"seconds;180"` + + NftablesFilterAllowAction string `config:"oneof(ACCEPT,RETURN);ACCEPT;non-zero,die-on-fail"` + NftablesMangleAllowAction string `config:"oneof(ACCEPT,RETURN);ACCEPT;non-zero,die-on-fail"` + NftablesFilterDenyAction string `config:"oneof(DROP,REJECT);DROP;non-zero,die-on-fail"` + + // MarkMask is the mask that Felix selects its nftables Mark bits from. Should be a 32 bit hexadecimal + // number with at least 8 bits set, none of which clash with any other mark bits in use on the system. + // [Default: 0xffff0000] + NftablesMarkMask uint32 `config:"mark-bitmask;0xffff0000;non-zero,die-on-fail"` + // State tracking. // internalOverrides contains our highest priority config source, generated from internal constraints @@ -435,6 +448,41 @@ type Config struct { useNodeResourceUpdates bool } +func (config *Config) FilterAllowAction() string { + if config.NFTablesMode == "Enabled" { + return config.NftablesFilterAllowAction + } + return config.IptablesFilterAllowAction +} + +func (config *Config) MangleAllowAction() string { + if config.NFTablesMode == "Enabled" { + return config.NftablesMangleAllowAction + } + return config.IptablesMangleAllowAction +} + +func (config *Config) FilterDenyAction() string { + if config.NFTablesMode == "Enabled" { + return config.NftablesFilterDenyAction + } + return config.IptablesFilterDenyAction +} + +func (config *Config) MarkMask() uint32 { + if config.NFTablesMode == "Enabled" { + return config.NftablesMarkMask + } + return config.IptablesMarkMask +} + +func (config *Config) TableRefreshInterval() time.Duration { + if config.NFTablesMode == "Enabled" { + return config.NftablesRefreshInterval + } + return config.IptablesRefreshInterval +} + // Copy makes a copy of the object. Internal state is deep copied but config parameters are only shallow copied. // This saves work since updates to the copy will trigger the config params to be recalculated. func (config *Config) Copy() *Config { @@ -1085,7 +1133,7 @@ func (config *Config) OverrideParam(name, value string) (bool, error) { // RouteTableIndices compares provided args for the deprecated RoutTableRange arg // and the newer RouteTableRanges arg, giving precedence to the newer arg if it's explicitly-set func (config *Config) RouteTableIndices() []idalloc.IndexRange { - if config.RouteTableRanges == nil || len(config.RouteTableRanges) == 0 { + if len(config.RouteTableRanges) == 0 { if config.RouteTableRange != (idalloc.IndexRange{}) { log.Warn("Proceeding with `RouteTableRange` config option. This field has been deprecated in favor of `RouteTableRanges`.") return []idalloc.IndexRange{ diff --git a/felix/dataplane/driver.go b/felix/dataplane/driver.go index d36edfd341d..e7adb604f14 100644 --- a/felix/dataplane/driver.go +++ b/felix/dataplane/driver.go @@ -45,8 +45,10 @@ import ( "github.com/projectcalico/calico/felix/idalloc" "github.com/projectcalico/calico/felix/ifacemonitor" "github.com/projectcalico/calico/felix/ipsets" + "github.com/projectcalico/calico/felix/iptables" "github.com/projectcalico/calico/felix/logutils" "github.com/projectcalico/calico/felix/markbits" + "github.com/projectcalico/calico/felix/nftables" "github.com/projectcalico/calico/felix/rules" "github.com/projectcalico/calico/felix/wireguard" "github.com/projectcalico/calico/libcalico-go/lib/health" @@ -81,7 +83,7 @@ func StartDataplaneDriver(configParams *config.Config, log.Panic("Starting dataplane with nil callback func.") } - allowedMarkBits := configParams.IptablesMarkMask + allowedMarkBits := configParams.MarkMask() if configParams.BPFEnabled { // In BPF mode, the BPF programs use mark bits that are not configurable. Make sure that those // bits are covered by our allowed mask. @@ -90,7 +92,7 @@ func StartDataplaneDriver(configParams *config.Config, "Name": "felix-iptables", "MarkMask": allowedMarkBits, "RequiredBPFBits": tcdefs.MarksMask, - }).Panic("IptablesMarkMask doesn't cover bits that are used (unconditionally) by eBPF mode.") + }).Panic("IptablesMarkMask/NftablesMarkMask doesn't cover bits that are used (unconditionally) by eBPF mode.") } allowedMarkBits ^= allowedMarkBits & tcdefs.MarksMask log.WithField("updatedBits", allowedMarkBits).Info( @@ -230,12 +232,12 @@ func StartDataplaneDriver(configParams *config.Config, OpenStackMetadataIP: net.ParseIP(configParams.MetadataAddr), OpenStackMetadataPort: uint16(configParams.MetadataPort), - IptablesMarkAccept: markAccept, - IptablesMarkPass: markPass, - IptablesMarkScratch0: markScratch0, - IptablesMarkScratch1: markScratch1, - IptablesMarkEndpoint: markEndpointMark, - IptablesMarkNonCaliEndpoint: markEndpointNonCaliEndpoint, + MarkAccept: markAccept, + MarkPass: markPass, + MarkScratch0: markScratch0, + MarkScratch1: markScratch1, + MarkEndpoint: markEndpointMark, + MarkNonCaliEndpoint: markEndpointNonCaliEndpoint, VXLANEnabled: configParams.Encapsulation.VXLANEnabled, VXLANEnabledV6: configParams.Encapsulation.VXLANEnabledV6, @@ -255,17 +257,17 @@ func StartDataplaneDriver(configParams *config.Config, WireguardEnabledV6: configParams.WireguardEnabledV6, WireguardInterfaceName: configParams.WireguardInterfaceName, WireguardInterfaceNameV6: configParams.WireguardInterfaceNameV6, - WireguardIptablesMark: markWireguard, + WireguardMark: markWireguard, WireguardListeningPort: configParams.WireguardListeningPort, WireguardListeningPortV6: configParams.WireguardListeningPortV6, WireguardEncryptHostTraffic: configParams.WireguardHostEncryptionEnabled, RouteSource: configParams.RouteSource, - IptablesLogPrefix: configParams.LogPrefix, - EndpointToHostAction: configParams.DefaultEndpointToHostAction, - IptablesFilterAllowAction: configParams.IptablesFilterAllowAction, - IptablesMangleAllowAction: configParams.IptablesMangleAllowAction, - IptablesFilterDenyAction: configParams.IptablesFilterDenyAction, + LogPrefix: configParams.LogPrefix, + EndpointToHostAction: configParams.DefaultEndpointToHostAction, + FilterAllowAction: configParams.FilterAllowAction(), + MangleAllowAction: configParams.MangleAllowAction(), + FilterDenyAction: configParams.FilterDenyAction(), FailsafeInboundHostPorts: configParams.FailsafeInboundHostPorts, FailsafeOutboundHostPorts: configParams.FailsafeOutboundHostPorts, @@ -276,7 +278,7 @@ func StartDataplaneDriver(configParams *config.Config, IptablesNATOutgoingInterfaceFilter: configParams.IptablesNATOutgoingInterfaceFilter, NATOutgoingAddress: configParams.NATOutgoingAddress, BPFEnabled: configParams.BPFEnabled, - BPFForceTrackPacketsFromIfaces: configParams.BPFForceTrackPacketsFromIfaces, + BPFForceTrackPacketsFromIfaces: replaceWildcards(configParams.NFTablesMode == "Enabled", configParams.BPFForceTrackPacketsFromIfaces), ServiceLoopPrevention: configParams.ServiceLoopPrevention, }, Wireguard: wireguard.Config{ @@ -302,7 +304,7 @@ func StartDataplaneDriver(configParams *config.Config, VXLANMTUV6: configParams.VXLANMTUV6, VXLANPort: configParams.VXLANPort, IptablesBackend: configParams.IptablesBackend, - IptablesRefreshInterval: configParams.IptablesRefreshInterval, + TableRefreshInterval: configParams.TableRefreshInterval(), RouteSyncDisabled: configParams.RouteSyncDisabled, RouteRefreshInterval: configParams.RouteRefreshInterval, DeviceRouteSourceAddress: configParams.DeviceRouteSourceAddress, @@ -375,6 +377,7 @@ func StartDataplaneDriver(configParams *config.Config, RouteTableManager: routeTableIndexAllocator, MTUIfacePattern: configParams.MTUIfacePattern, BPFExcludeCIDRsFromNAT: configParams.BPFExcludeCIDRsFromNAT, + BPFRedirectToPeer: configParams.BPFRedirectToPeer, ServiceLoopPrevention: configParams.ServiceLoopPrevention, KubeClientSet: k8sClientSet, @@ -434,3 +437,18 @@ func ConfigurePrometheusMetrics(configParams *config.Config) { } } } + +func replaceWildcards(nftEnabled bool, s []string) []string { + for i, v := range s { + s[i] = replaceWildcard(nftEnabled, v) + } + return s +} + +func replaceWildcard(nftEnabled bool, s string) string { + // Need to replace the "+" wildcard with "*" for nftables. + if nftEnabled && strings.HasSuffix(s, iptables.Wildcard) { + return s[:len(s)-1] + nftables.Wildcard + } + return s +} diff --git a/felix/dataplane/linux/bpf_ep_mgr.go b/felix/dataplane/linux/bpf_ep_mgr.go index 8060b4a83bc..2f1de36b871 100644 --- a/felix/dataplane/linux/bpf_ep_mgr.go +++ b/felix/dataplane/linux/bpf_ep_mgr.go @@ -1,6 +1,6 @@ //go:build !windows -// Copyright (c) 2020-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -111,6 +111,14 @@ var ( jumpMapV6PolicyKey = make([]byte, 4) ) +type XDPMode int + +const ( + XDPModeAll XDPMode = iota + XDPModeOnly + XDPModeNone +) + func init() { prometheus.MustRegister(bpfEndpointsGauge) prometheus.MustRegister(bpfDirtyEndpointsGauge) @@ -328,9 +336,10 @@ type bpfEndpointManager struct { updatePolicyProgramFn func(rules polprog.Rules, polDir string, ap attachPoint, ipFamily proto.IPVersion) error // HEP processing. - hostIfaceToEpMap map[string]proto.HostEndpoint - wildcardHostEndpoint proto.HostEndpoint - wildcardExists bool + hostIfaceToEpMap map[string]proto.HostEndpoint + wildcardHostEndpoint proto.HostEndpoint + wildcardExists bool + hostIfaceToSlaveDevices map[string]set.Set[string] // UT-able BPF dataplane interface. dp bpfDataplane @@ -356,9 +365,10 @@ type bpfEndpointManager struct { hostNetworkedNATMode hostNetworkedNATMode bpfPolicyDebugEnabled bool + bpfRedirectToPeer string - routeTableV4 routetable.RouteTableInterface - routeTableV6 routetable.RouteTableInterface + routeTableV4 *routetable.ClassView + routeTableV6 *routetable.ClassView services map[serviceKey][]ip.CIDR dirtyServices set.Set[serviceKey] natExcludedCIDRs *ip.CIDRTrie @@ -404,6 +414,7 @@ type bpfAllowChainRenderer interface { type ManagerWithHEPUpdate interface { Manager OnHEPUpdate(hostIfaceToEpMap map[string]proto.HostEndpoint) + GetIfaceQDiscInfo(ifaceName string) (bool, int, int) } func NewTestEpMgr( @@ -413,27 +424,28 @@ func NewTestEpMgr( ) (ManagerWithHEPUpdate, error) { return newBPFEndpointManager(nil, config, bpfmaps, true, workloadIfaceRegex, idalloc.New(), idalloc.New(), rules.NewRenderer(rules.Config{ - BPFEnabled: true, - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, - KubeIPVSSupportEnabled: true, - WorkloadIfacePrefixes: []string{"cali", "tap"}, - VXLANPort: 4789, - VXLANVNI: 4096, + BPFEnabled: true, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, + KubeIPVSSupportEnabled: true, + WorkloadIfacePrefixes: []string{"cali", "tap"}, + VXLANPort: 4789, + VXLANVNI: 4096, }), generictables.NewNoopTable(), generictables.NewNoopTable(), nil, logutils.NewSummarizer("test"), - new(environment.FakeFeatureDetector), + &routetable.DummyTable{}, + &routetable.DummyTable{}, nil, nil, 1500, @@ -453,7 +465,8 @@ func newBPFEndpointManager( iptablesFilterTableV6 Table, livenessCallback func(), opReporter logutils.OpRecorder, - featureDetector environment.FeatureDetectorIface, + mainRouteTableV4 routetable.Interface, + mainRouteTableV6 routetable.Interface, healthAggregator *health.HealthAggregator, dataplanefeatures *environment.Features, bpfIfaceMTU int, @@ -475,6 +488,7 @@ func newBPFEndpointManager( profilesToWorkloads: map[proto.ProfileID]set.Set[any]{}, dirtyIfaceNames: set.New[string](), bpfLogLevel: config.BPFLogLevel, + logFilters: config.BPFLogFilters, hostname: config.Hostname, fibLookupEnabled: fibLookupEnabled, dataIfaceRegex: config.BPFDataIfacePattern, @@ -498,12 +512,13 @@ func newBPFEndpointManager( // Note: the allocators only allocate a fraction of the map, the // rest is reserved for sub-programs generated if a single program // would be too large. - jumpMapAlloc: newJumpMapAlloc(jump.TCMaxEntryPoints), - xdpJumpMapAlloc: newJumpMapAlloc(jump.XDPMaxEntryPoints), - ruleRenderer: iptablesRuleRenderer, - onStillAlive: livenessCallback, - hostIfaceToEpMap: map[string]proto.HostEndpoint{}, - opReporter: opReporter, + jumpMapAlloc: newJumpMapAlloc(jump.TCMaxEntryPoints), + xdpJumpMapAlloc: newJumpMapAlloc(jump.XDPMaxEntryPoints), + ruleRenderer: iptablesRuleRenderer, + onStillAlive: livenessCallback, + hostIfaceToEpMap: map[string]proto.HostEndpoint{}, + hostIfaceToSlaveDevices: map[string]set.Set[string]{}, + opReporter: opReporter, // ipv6Enabled Should be set to config.Ipv6Enabled, but for now it is better // to set it to BPFIpv6Enabled which is a dedicated flag for development of IPv6. // TODO: set ipv6Enabled to config.Ipv6Enabled when IPv6 support is complete @@ -511,6 +526,7 @@ func newBPFEndpointManager( rpfEnforceOption: config.BPFEnforceRPF, bpfDisableGROForIfaces: config.BPFDisableGROForIfaces, bpfPolicyDebugEnabled: config.BPFPolicyDebugEnabled, + bpfRedirectToPeer: config.BPFRedirectToPeer, polNameToMatchIDs: map[string]set.Set[polprog.RuleMatchID]{}, dirtyRules: set.New[polprog.RuleMatchID](), @@ -569,33 +585,8 @@ func newBPFEndpointManager( if m.hostNetworkedNATMode != hostNetworkedNATDisabled { log.Infof("HostNetworkedNATMode is %d", m.hostNetworkedNATMode) - if m.v4 != nil { - m.routeTableV4 = routetable.New( - []string{dataplanedefs.BPFInDev}, - uint8(4), - config.NetlinkTimeout, - nil, // deviceRouteSourceAddress - config.DeviceRouteProtocol, - true, // removeExternalRoutes - unix.RT_TABLE_MAIN, - opReporter, - featureDetector, - ) - } - if m.v6 != nil { - m.routeTableV6 = routetable.New( - []string{dataplanedefs.BPFInDev}, - uint8(6), - config.NetlinkTimeout, - nil, // deviceRouteSourceAddress - config.DeviceRouteProtocol, - true, // removeExternalRoutes - unix.RT_TABLE_MAIN, - opReporter, - featureDetector, - ) - } - + m.routeTableV4 = routetable.NewClassView(routetable.RouteClassBPFSpecial, mainRouteTableV4) + m.routeTableV6 = routetable.NewClassView(routetable.RouteClassBPFSpecial, mainRouteTableV6) m.services = make(map[serviceKey][]ip.CIDR) m.dirtyServices = set.New[serviceKey]() m.natExcludedCIDRs = ip.NewCIDRTrie() @@ -767,7 +758,16 @@ func (m *bpfEndpointManager) withIface(ifaceName string, fn func(iface *bpfInter m.dirtyIfaceNames.Add(ifaceName) } -func (m *bpfEndpointManager) updateHostIP(ip net.IP, ipFamily int) { +func (m *bpfEndpointManager) GetIfaceQDiscInfo(ifaceName string) (bool, int, int) { + qdisc := m.nameToIface[ifaceName].dpState.qdisc + return qdisc.valid, qdisc.prio, qdisc.handle +} + +func (m *bpfEndpointManager) updateHostIP(ipAddr string, ipFamily int) { + ip, _, err := net.ParseCIDR(ipAddr) + if err != nil { + ip = net.ParseIP(ipAddr) + } if ip != nil { if ipFamily == 4 { m.v4.hostIP = ip @@ -778,10 +778,13 @@ func (m *bpfEndpointManager) updateHostIP(ip net.IP, ipFamily int) { // but taking it now makes us robust to refactoring. m.ifacesLock.Lock() for ifaceName := range m.nameToIface { - m.dirtyIfaceNames.Add(ifaceName) + m.withIface(ifaceName, func(iface *bpfInterface) (forceDirty bool) { + iface.dpState.v4Readiness = ifaceNotReady + iface.dpState.v6Readiness = ifaceNotReady + return true + }) } m.ifacesLock.Unlock() - // We use host IP as the source when routing service for the ctlb workaround. We // need to update those routes, so make them all dirty. for svc := range m.services { @@ -822,12 +825,12 @@ func (m *bpfEndpointManager) OnUpdate(msg interface{}) { case *proto.HostMetadataUpdate: if m.v4 != nil && msg.Hostname == m.hostname { log.WithField("HostMetadataUpdate", msg).Infof("Host IP changed: %s", msg.Ipv4Addr) - m.updateHostIP(net.ParseIP(msg.Ipv4Addr), 4) + m.updateHostIP(msg.Ipv4Addr, 4) } case *proto.HostMetadataV6Update: if m.v6 != nil && msg.Hostname == m.hostname { log.WithField("HostMetadataV6Update", msg).Infof("Host IPv6 changed: %s", msg.Ipv6Addr) - m.updateHostIP(net.ParseIP(msg.Ipv6Addr), 6) + m.updateHostIP(msg.Ipv6Addr, 6) } case *proto.HostMetadataV4V6Update: if msg.Hostname != m.hostname { @@ -835,11 +838,11 @@ func (m *bpfEndpointManager) OnUpdate(msg interface{}) { } if m.v4 != nil { log.WithField("HostMetadataV4V6Update", msg).Infof("Host IP changed: %s", msg.Ipv4Addr) - m.updateHostIP(net.ParseIP(msg.Ipv4Addr), 4) + m.updateHostIP(msg.Ipv4Addr, 4) } if m.v6 != nil { log.WithField("HostMetadataV4V6Update", msg).Infof("Host IPv6 changed: %s", msg.Ipv6Addr) - m.updateHostIP(net.ParseIP(msg.Ipv6Addr), 6) + m.updateHostIP(msg.Ipv6Addr, 6) } case *proto.ServiceUpdate: m.onServiceUpdate(msg) @@ -854,7 +857,7 @@ func (m *bpfEndpointManager) onRouteUpdate(update *proto.RouteUpdate) { if update.Type == proto.RouteType_LOCAL_TUNNEL { ip, _, err := net.ParseCIDR(update.Dst) if err != nil { - log.WithField("local tunnel cird", update.Dst).WithError(err).Warn("not parsable") + log.WithField("local tunnel cidr", update.Dst).WithError(err).Warn("not parsable") return } if m.v6 != nil { @@ -953,6 +956,7 @@ func (m *bpfEndpointManager) reclaimFilterIdx(name string, iface *bpfInterface) if err := m.jumpMapAlloc.Put(iface.dpState.filterIdx[attachHook], name); err != nil { log.WithError(err).Errorf("Filter hook %s", attachHook) } + iface.dpState.filterIdx[attachHook] = -1 } } @@ -991,6 +995,7 @@ func (m *bpfEndpointManager) updateIfaceStateMap(name string, iface *bpfInterfac if iface.dpState.v6Readiness != ifaceNotReady { flags |= ifstate.FlgIPv6Ready } + v := ifstate.NewValue(flags, name, iface.dpState.v4.policyIdx[hook.XDP], iface.dpState.v4.policyIdx[hook.Ingress], @@ -1099,7 +1104,14 @@ func (m *bpfEndpointManager) onInterfaceUpdate(update *ifaceStateUpdate) { } masterIfIndex := 0 + prevMasterIfIndex := 0 curIfaceType := IfaceTypeUnknown + prevIfaceType := IfaceTypeUnknown + if val, ok := m.nameToIface[update.Name]; ok { + prevIfaceType = val.info.ifaceType + prevMasterIfIndex = val.info.masterIfIndex + } + if update.State != ifacemonitor.StateNotPresent && !m.isWorkloadIface(update.Name) { // Determine the type of interface. // These include host, bond, slave, ipip, wireguard, l3. @@ -1115,10 +1127,6 @@ func (m *bpfEndpointManager) onInterfaceUpdate(update *ifaceStateUpdate) { curIfaceType = m.getIfaceTypeFromLink(link) masterIfIndex = link.Attrs().MasterIndex } - prevIfaceType := IfaceTypeUnknown - if val, ok := m.nameToIface[update.Name]; ok { - prevIfaceType = val.info.ifaceType - } if prevIfaceType != curIfaceType { if curIfaceType == IfaceTypeBondSlave { // Remove the Tc program. @@ -1130,6 +1138,51 @@ func (m *bpfEndpointManager) onInterfaceUpdate(update *ifaceStateUpdate) { log.WithError(err).Warnf("Failed to detach old programs from now bonding device '%s'", update.Name) } } + } else if curIfaceType == IfaceTypeBond { + // create an entry in the hostIfaceToSlaveDevices + if _, ok := m.hostIfaceToSlaveDevices[update.Name]; !ok { + m.hostIfaceToSlaveDevices[update.Name] = set.New[string]() + } + } + } + } + + // Manage bond slaves. + if !m.isWorkloadIface(update.Name) && curIfaceType != prevIfaceType { + if curIfaceType == IfaceTypeBondSlave { + /* Interface has been added to a bond. + * Add this interface to the list of slave devices + * of the master. + */ + netiface, err := m.dp.interfaceByIndex(masterIfIndex) + if err != nil { + log.WithError(err).Warn("Failed to get master interface name. Slave devices not updated") + } else { + // Slave interface update comes first. + if _, ok := m.hostIfaceToSlaveDevices[netiface.Name]; !ok { + m.hostIfaceToSlaveDevices[netiface.Name] = set.New[string]() + } + m.hostIfaceToSlaveDevices[netiface.Name].Add(update.Name) + } + } else { + /* Interface is either removed from the bond or deleted. + * In such cases, remove the interface from the list of slave devices. + */ + if prevIfaceType == IfaceTypeBondSlave { + netiface, err := m.dp.interfaceByIndex(prevMasterIfIndex) + if err != nil { + log.WithError(err).Warn("Failed to get master interface name. Slave devices not updated") + } else { + if _, ok := m.hostIfaceToSlaveDevices[netiface.Name]; ok { + m.hostIfaceToSlaveDevices[netiface.Name].Discard(update.Name) + } + } + } + /* Interface is not a bond anymore. Remove the interface + * from the map. + */ + if prevIfaceType == IfaceTypeBond { + delete(m.hostIfaceToSlaveDevices, update.Name) } } } @@ -1228,6 +1281,7 @@ func (m *bpfEndpointManager) onPolicyUpdate(msg *proto.ActivePolicyUpdate) { polID := *msg.Id log.WithField("id", polID).Debug("Policy update") m.policies[polID] = msg.Policy + // Note, polID includes the tier name as well as the policy name. m.markEndpointsDirty(m.policiesToWorkloads[polID], "policy") if m.bpfPolicyDebugEnabled { m.updatePolicyCache(polID.Name, "Policy", m.policies[polID].InboundRules, m.policies[polID].OutboundRules) @@ -1239,6 +1293,7 @@ func (m *bpfEndpointManager) onPolicyUpdate(msg *proto.ActivePolicyUpdate) { func (m *bpfEndpointManager) onPolicyRemove(msg *proto.ActivePolicyRemove) { polID := *msg.Id log.WithField("id", polID).Debug("Policy removed") + // Note, polID includes the tier name as well as the policy name. m.markEndpointsDirty(m.policiesToWorkloads[polID], "policy") delete(m.policies, polID) delete(m.policiesToWorkloads, polID) @@ -1305,8 +1360,9 @@ func (m *bpfEndpointManager) markEndpointsDirty(ids set.Set[any], kind string) { } } } else { - log.Debugf("Mark host iface dirty, for host %v change", kind) + log.Debugf("Mark host iface dirty %v, for host %v change", id, kind) m.dirtyIfaceNames.Add(id) + m.dirtyIfaceNames.AddSet(m.getBondSlaves(id)) } } return nil @@ -1679,7 +1735,7 @@ func (m *bpfEndpointManager) reportHealth(ready bool, detail string) { }) } -func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfaceState, error) { +func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface, masterIface string, xdpMode XDPMode) (bpfInterfaceState, error) { var ( err error up bool @@ -1687,7 +1743,6 @@ func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfac ) m.ifacesLock.Lock() - ifaceName := iface m.withIface(iface, func(iface *bpfInterface) bool { up = iface.info.ifaceIsUp() state = iface.dpState @@ -1698,16 +1753,19 @@ func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfac log.WithField("iface", iface).Debug("Ignoring interface that is down") return state, nil } - if err := m.dataIfaceStateFillJumps(ifaceName, &state); err != nil { - return state, err - } - _, err = m.dp.ensureQdisc(iface) - if err != nil { - return state, err + hepIface := iface + if xdpMode != XDPModeOnly { + _, err = m.dp.ensureQdisc(iface) + if err != nil { + return state, err + } + } else { + hepIface = masterIface } + var hepPtr *proto.HostEndpoint - if hep, hepExists := m.hostIfaceToEpMap[iface]; hepExists { + if hep, hepExists := m.hostIfaceToEpMap[hepIface]; hepExists { hepPtr = &hep } @@ -1718,6 +1776,10 @@ func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfac var xdpAP4, xdpAP6 *xdp.AttachPoint tcAttachPoint := m.calculateTCAttachPoint(iface) + if err := m.dataIfaceStateFillJumps(tcAttachPoint, xdpMode, &state); err != nil { + return state, err + } + xdpAttachPoint := &xdp.AttachPoint{ AttachPoint: bpf.AttachPoint{ Hook: hook.XDP, @@ -1732,12 +1794,12 @@ func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfac go func() { defer parallelWG.Done() ingressAP6, egressAP6, xdpAP6, err6 = m.v6.applyPolicyToDataIface(iface, hepPtr, &state, - tcAttachPoint, xdpAttachPoint) + tcAttachPoint, xdpAttachPoint, xdpMode) }() } if m.v4 != nil { ingressAP4, egressAP4, xdpAP4, err4 = m.v4.applyPolicyToDataIface(iface, hepPtr, &state, - tcAttachPoint, xdpAttachPoint) + tcAttachPoint, xdpAttachPoint, xdpMode) } parallelWG.Wait() @@ -1758,10 +1820,12 @@ func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfac go func() { defer parallelWG.Done() xdpAP := mergeAttachPoints(xdpAP4, xdpAP6) - if hepPtr != nil && len(hepPtr.UntrackedTiers) == 1 && xdpAP != nil { - _, xdpErr = m.dp.ensureProgramAttached(xdpAP) - } else { - xdpErr = m.dp.ensureNoProgram(xdpAP) + if xdpAP != nil { + if hepPtr != nil && len(hepPtr.UntrackedTiers) == 1 { + _, xdpErr = m.dp.ensureProgramAttached(xdpAP) + } else { + xdpErr = m.dp.ensureNoProgram(xdpAP) + } } }() @@ -1830,6 +1894,8 @@ func (m *bpfEndpointManager) applyProgramsToDirtyDataInterfaces() { } return nil } + xdpMode := XDPModeAll + masterName := "" m.ifacesLock.Lock() val, ok := m.nameToIface[iface] m.ifacesLock.Unlock() @@ -1841,21 +1907,27 @@ func (m *bpfEndpointManager) applyProgramsToDirtyDataInterfaces() { masterIfa, err := m.dp.interfaceByIndex(val.info.masterIfIndex) if err != nil { log.Warnf("Failed to get master interface details for '%s'. Continuing to attach program", iface) - } else if !m.isDataIface(masterIfa.Name) { - log.Warnf("Master interface '%s' ignored. Add it to the bpfDataIfacePattern config", masterIfa.Name) } else { - log.WithField("iface", iface).Debug( - "Ignoring bonding slave interface") - return set.RemoveItem + masterName = masterIfa.Name + if !m.isDataIface(masterIfa.Name) { + log.Warnf("Master interface '%s' ignored. Add it to the bpfDataIfacePattern config", masterIfa.Name) + } else { + log.WithField("iface", iface).Debug( + "Attaching xdp only") + xdpMode = XDPModeOnly + } } } + if val.info.ifaceType == IfaceTypeBond { + xdpMode = XDPModeNone + } } m.opReporter.RecordOperation("update-data-iface") wg.Add(1) go func(ifaceName string) { defer wg.Done() - state, err := m.doApplyPolicyToDataIface(ifaceName) + state, err := m.doApplyPolicyToDataIface(ifaceName, masterName, xdpMode) m.ifacesLock.Lock() m.withIface(ifaceName, func(bpfIface *bpfInterface) bool { bpfIface.dpState = state @@ -2010,23 +2082,25 @@ func (m *bpfEndpointManager) allocJumpIndicesForWEP(ifaceName string, idx *bpfIn return nil } -func (m *bpfEndpointManager) allocJumpIndicesForDataIface(ifaceName string, idx *bpfInterfaceJumpIndices) error { +func (m *bpfEndpointManager) allocJumpIndicesForDataIface(ifaceName string, xdpMode XDPMode, idx *bpfInterfaceJumpIndices) error { var err error - if idx.policyIdx[hook.Ingress] == -1 { - idx.policyIdx[hook.Ingress], err = m.jumpMapAlloc.Get(ifaceName) - if err != nil { - return err + if xdpMode != XDPModeOnly { + if idx.policyIdx[hook.Ingress] == -1 { + idx.policyIdx[hook.Ingress], err = m.jumpMapAlloc.Get(ifaceName) + if err != nil { + return err + } } - } - if idx.policyIdx[hook.Egress] == -1 { - idx.policyIdx[hook.Egress], err = m.jumpMapAlloc.Get(ifaceName) - if err != nil { - return err + if idx.policyIdx[hook.Egress] == -1 { + idx.policyIdx[hook.Egress], err = m.jumpMapAlloc.Get(ifaceName) + if err != nil { + return err + } } } - if idx.policyIdx[hook.XDP] == -1 { + if xdpMode != XDPModeNone && idx.policyIdx[hook.XDP] == -1 { idx.policyIdx[hook.XDP], err = m.xdpJumpMapAlloc.Get(ifaceName) if err != nil { return err @@ -2036,12 +2110,12 @@ func (m *bpfEndpointManager) allocJumpIndicesForDataIface(ifaceName string, idx return nil } -func (m *bpfEndpointManager) wepStateFillJumps(ifaceName string, state *bpfInterfaceState) error { +func (m *bpfEndpointManager) wepStateFillJumps(ap *tc.AttachPoint, state *bpfInterfaceState) error { var err error // Allocate indices for IPv4 if m.v4 != nil { - err = m.allocJumpIndicesForWEP(ifaceName, &state.v4) + err = m.allocJumpIndicesForWEP(ap.IfaceName(), &state.v4) if err != nil { return err } @@ -2049,59 +2123,80 @@ func (m *bpfEndpointManager) wepStateFillJumps(ifaceName string, state *bpfInter // Allocate indices for IPv6 if m.v6 != nil { - err = m.allocJumpIndicesForWEP(ifaceName, &state.v6) + err = m.allocJumpIndicesForWEP(ap.IfaceName(), &state.v6) if err != nil { return err } } - if m.bpfLogLevel == "debug" { + if ap.LogLevel == "debug" { if state.filterIdx[hook.Ingress] == -1 { - state.filterIdx[hook.Ingress], err = m.jumpMapAlloc.Get(ifaceName) + state.filterIdx[hook.Ingress], err = m.jumpMapAlloc.Get(ap.IfaceName()) if err != nil { return err } } if state.filterIdx[hook.Egress] == -1 { - state.filterIdx[hook.Egress], err = m.jumpMapAlloc.Get(ifaceName) + state.filterIdx[hook.Egress], err = m.jumpMapAlloc.Get(ap.IfaceName()) if err != nil { return err } } + } else { + for _, attachHook := range []hook.Hook{hook.Ingress, hook.Egress} { + if err := m.jumpMapDelete(attachHook, state.filterIdx[attachHook]); err != nil { + log.WithError(err).Warn("Filter program may leak.") + } + if err := m.jumpMapAlloc.Put(state.filterIdx[attachHook], ap.IfaceName()); err != nil { + log.WithError(err).Errorf("Filter hook %s", attachHook) + } + state.filterIdx[attachHook] = -1 + } } + return nil } -func (m *bpfEndpointManager) dataIfaceStateFillJumps(ifaceName string, state *bpfInterfaceState) error { +func (m *bpfEndpointManager) dataIfaceStateFillJumps(ap *tc.AttachPoint, xdpMode XDPMode, state *bpfInterfaceState) error { var err error if m.v4 != nil { - err = m.allocJumpIndicesForDataIface(ifaceName, &state.v4) + err = m.allocJumpIndicesForDataIface(ap.IfaceName(), xdpMode, &state.v4) if err != nil { return err } } if m.v6 != nil { - err = m.allocJumpIndicesForDataIface(ifaceName, &state.v6) + err = m.allocJumpIndicesForDataIface(ap.IfaceName(), xdpMode, &state.v6) if err != nil { return err } } - if m.bpfLogLevel == "debug" { + if ap.LogLevel == "debug" { if state.filterIdx[hook.Ingress] == -1 { - state.filterIdx[hook.Ingress], err = m.jumpMapAlloc.Get(ifaceName) + state.filterIdx[hook.Ingress], err = m.jumpMapAlloc.Get(ap.IfaceName()) if err != nil { return err } } if state.filterIdx[hook.Egress] == -1 { - state.filterIdx[hook.Egress], err = m.jumpMapAlloc.Get(ifaceName) + state.filterIdx[hook.Egress], err = m.jumpMapAlloc.Get(ap.IfaceName()) if err != nil { return err } } + } else { + for _, attachHook := range []hook.Hook{hook.Ingress, hook.Egress} { + if err := m.jumpMapDelete(attachHook, state.filterIdx[attachHook]); err != nil { + log.WithError(err).Warn("Filter program may leak.") + } + if err := m.jumpMapAlloc.Put(state.filterIdx[attachHook], ap.IfaceName()); err != nil { + log.WithError(err).Errorf("Filter hook %s", attachHook) + } + state.filterIdx[attachHook] = -1 + } } return nil } @@ -2138,10 +2233,6 @@ func (m *bpfEndpointManager) doApplyPolicy(ifaceName string) (bpfInterfaceState, return state, nil } - if err := m.wepStateFillJumps(ifaceName, &state); err != nil { - return state, err - } - // Otherwise, the interface appears to be present but we may or may not have an endpoint from the // datastore. If we don't have an endpoint then we'll attach a program to block traffic and we'll // get the jump map ready to insert the policy if the endpoint shows up. @@ -2185,10 +2276,18 @@ func (m *bpfEndpointManager) doApplyPolicy(ifaceName string) (bpfInterfaceState, v4Readiness = ifaceNotReady v6Readiness = ifaceNotReady } + if _, err := m.dp.queryClassifier(ifindex, state.qdisc.handle, state.qdisc.prio, false); err != nil { + v4Readiness = ifaceNotReady + v6Readiness = ifaceNotReady + } } ap := m.calculateTCAttachPoint(ifaceName) + if err := m.wepStateFillJumps(ap, &state); err != nil { + return state, err + } + if m.v6 != nil { wg.Add(1) go func() { @@ -2242,7 +2341,10 @@ func (m *bpfEndpointManager) doApplyPolicy(ifaceName string) (bpfInterfaceState, return state, fmt.Errorf("ingress qdisc info (%v) does not equal egress qdisc info (%v)", ingressQdisc, egressQdisc) } - state.qdisc = ingressQdisc + + if attachPreamble { + state.qdisc = ingressQdisc + } if err4 != nil && err6 != nil { // This covers the case when we don't have hostIP on both paths. @@ -2289,7 +2391,7 @@ func (m *bpfEndpointManager) ensureProgramAttached(ap attachPoint) (qDiscInfo, e if err != nil { return qdisc, err } - if tcRes, ok := res.(*tc.AttachResult); ok { + if tcRes, ok := res.(tc.AttachResult); ok { qdisc.valid = true qdisc.prio = tcRes.Prio() qdisc.handle = tcRes.Handle() @@ -2383,7 +2485,6 @@ func (d *bpfEndpointManagerDataplane) wepApplyPolicyToDirection(readiness ifaceR endpoint *proto.WorkloadEndpoint, polDirection PolDirection, ap *tc.AttachPoint, ) (*tc.AttachPoint, error) { var policyIdx, filterIdx int - if d.hostIP == nil { // Do not bother and wait return nil, fmt.Errorf("unknown host IP") @@ -2439,12 +2540,10 @@ func (d *bpfEndpointManagerDataplane) wepApplyPolicy(ap *tc.AttachPoint, endpoint *proto.WorkloadEndpoint, polDirection PolDirection, ) error { var profileIDs []string - var tier *proto.TierInfo + var tiers []*proto.TierInfo if endpoint != nil { profileIDs = endpoint.ProfileIds - if len(endpoint.Tiers) != 0 { - tier = endpoint.Tiers[0] - } + tiers = endpoint.Tiers } else { log.WithField("name", ap.IfaceName()).Debug( "Workload interface with no endpoint in datastore, installing default-drop program.") @@ -2453,7 +2552,7 @@ func (d *bpfEndpointManagerDataplane) wepApplyPolicy(ap *tc.AttachPoint, m := d.mgr // If tier or profileIDs is nil, this will return an empty set of rules but updatePolicyProgram appends a // drop rule, giving us default drop behaviour in that case. - rules := m.extractRules(tier, profileIDs, polDirection) + rules := m.extractRules(tiers, profileIDs, polDirection) // If host-* endpoint is configured, add in its policy. if m.wildcardExists { @@ -2484,21 +2583,15 @@ func (d *bpfEndpointManagerDataplane) wepApplyPolicy(ap *tc.AttachPoint, func (m *bpfEndpointManager) addHostPolicy(rules *polprog.Rules, hostEndpoint *proto.HostEndpoint, polDirection PolDirection) { // When there is applicable pre-DNAT policy that does not explicitly Allow or Deny traffic, // we continue on to subsequent tiers and normal or AoF policy. - if len(hostEndpoint.PreDnatTiers) == 1 { - rules.HostPreDnatTiers = m.extractTiers(hostEndpoint.PreDnatTiers[0], polDirection, NoEndTierDrop) - } + rules.HostPreDnatTiers = m.extractTiers(hostEndpoint.PreDnatTiers, polDirection, NoEndTierDrop) // When there is applicable apply-on-forward policy that does not explicitly Allow or Deny // traffic, traffic is dropped. - if len(hostEndpoint.ForwardTiers) == 1 { - rules.HostForwardTiers = m.extractTiers(hostEndpoint.ForwardTiers[0], polDirection, EndTierDrop) - } + rules.HostForwardTiers = m.extractTiers(hostEndpoint.ForwardTiers, polDirection, EndTierDrop) // When there is applicable normal policy that does not explicitly Allow or Deny traffic, // traffic is dropped. - if len(hostEndpoint.Tiers) == 1 { - rules.HostNormalTiers = m.extractTiers(hostEndpoint.Tiers[0], polDirection, EndTierDrop) - } + rules.HostNormalTiers = m.extractTiers(hostEndpoint.Tiers, polDirection, EndTierDrop) rules.HostProfiles = m.extractProfiles(hostEndpoint.ProfileIds, polDirection) } @@ -2536,6 +2629,7 @@ func (d *bpfEndpointManagerDataplane) applyPolicyToDataIface( state *bpfInterfaceState, ap *tc.AttachPoint, apxdp *xdp.AttachPoint, + xdpMode XDPMode, ) (*tc.AttachPoint, *tc.AttachPoint, *xdp.AttachPoint, error) { ingressAttachPoint := *ap egressAttachPoint := *ap @@ -2546,20 +2640,24 @@ func (d *bpfEndpointManagerDataplane) applyPolicyToDataIface( var xdpAP *xdp.AttachPoint var ingressErr, egressErr, xdpErr error - parallelWG.Add(2) - go func() { - defer parallelWG.Done() - ingressAP, ingressErr = d.attachDataIfaceProgram(ifaceName, ep, PolDirnIngress, state, &ingressAttachPoint) - }() + if xdpMode != XDPModeNone { + parallelWG.Add(1) + go func() { + defer parallelWG.Done() + xdpAP, xdpErr = d.attachXDPProgram(&xdpAttachPoint, ep, state) + }() + } - go func() { - defer parallelWG.Done() - xdpAP, xdpErr = d.attachXDPProgram(&xdpAttachPoint, ep, state) - }() + if xdpMode != XDPModeOnly { + parallelWG.Add(1) + go func() { + defer parallelWG.Done() + ingressAP, ingressErr = d.attachDataIfaceProgram(ifaceName, ep, PolDirnIngress, state, &ingressAttachPoint) + }() - egressAP, egressErr = d.attachDataIfaceProgram(ifaceName, ep, PolDirnEgress, state, &egressAttachPoint) + egressAP, egressErr = d.attachDataIfaceProgram(ifaceName, ep, PolDirnEgress, state, &egressAttachPoint) + } parallelWG.Wait() - return ingressAP, egressAP, xdpAP, errors.Join(ingressErr, egressErr, xdpErr) } @@ -2653,7 +2751,7 @@ func (d *bpfEndpointManagerDataplane) attachXDPProgram(ap *xdp.AttachPoint, ep * ap.Log().Infof("Building program for untracked policy hep=%v, family=%v", ep.Name, d.ipFamily) rules := polprog.Rules{ ForHostInterface: true, - HostNormalTiers: m.extractTiers(ep.UntrackedTiers[0], PolDirnIngress, false), + HostNormalTiers: m.extractTiers(ep.UntrackedTiers, PolDirnIngress, false), ForXDP: true, } ap.Log().Infof("Rules: %v", rules) @@ -2668,6 +2766,11 @@ func (d *bpfEndpointManagerDataplane) attachXDPProgram(ap *xdp.AttachPoint, ep * // On a workload endpoint, ingress is towards the workload. type PolDirection int +const ( + PolDirnIngress PolDirection = iota + PolDirnEgress +) + func (polDirection PolDirection) RuleDir() string { if polDirection == PolDirnIngress { return "Ingress" @@ -2675,11 +2778,6 @@ func (polDirection PolDirection) RuleDir() string { return "Egress" } -const ( - PolDirnIngress PolDirection = iota - PolDirnEgress -) - func (polDirection PolDirection) Inverse() PolDirection { if polDirection == PolDirnIngress { return PolDirnEgress @@ -2688,7 +2786,11 @@ func (polDirection PolDirection) Inverse() PolDirection { } func (m *bpfEndpointManager) apLogFilter(ap *tc.AttachPoint, iface string) (string, string) { - if m.logFilters == nil { + if len(m.logFilters) == 0 { + return m.bpfLogLevel, "" + } + + if m.bpfLogLevel != "debug" { return m.bpfLogLevel, "" } @@ -2696,21 +2798,26 @@ func (m *bpfEndpointManager) apLogFilter(ap *tc.AttachPoint, iface string) (stri if !ok { if ap.Type == tcdefs.EpTypeWorkload { if exp, ok := m.logFilters["weps"]; ok { + log.WithField("iface", iface).Debugf("Log filter for weps: %s", exp) return m.bpfLogLevel, exp } } if ap.Type == tcdefs.EpTypeHost { if exp, ok := m.logFilters["heps"]; ok { + log.WithField("iface", iface).Debugf("Log filter for heps: %s", exp) return m.bpfLogLevel, exp } } if exp, ok := m.logFilters["all"]; ok { + log.WithField("iface", iface).Debugf("Log filter for all: %s", exp) return m.bpfLogLevel, exp } + log.WithField("iface", iface).Debug("No log filter") return "off", "" } + log.WithField("iface", iface).Debugf("Log filter: %s", exp) return m.bpfLogLevel, exp } @@ -2761,6 +2868,12 @@ func (m *bpfEndpointManager) calculateTCAttachPoint(ifaceName string) *tc.Attach ap.Wg6Port = m.wg6Port ap.NATin = uint32(m.natInIdx) ap.NATout = uint32(m.natOutIdx) + + if m.bpfRedirectToPeer == "Enabled" { + ap.RedirectPeer = true + } else if (ap.Type == tcdefs.EpTypeTunnel || ap.Type == tcdefs.EpTypeL3Device) && m.bpfRedirectToPeer == "L2Only" { + ap.RedirectPeer = false + } } else { ap.ExtToServiceConnmark = uint32(m.bpfExtToServiceConnmark) } @@ -2828,57 +2941,59 @@ const ( NoEndTierDrop = false ) -func (m *bpfEndpointManager) extractTiers(tier *proto.TierInfo, direction PolDirection, endTierDrop bool) (rTiers []polprog.Tier) { +// Given a slice of TierInfo - as present on workload and host endpoints - that actually consists +// only of tier and policy NAMEs, build and return a slice of tier data that includes all of the +// implied policy rules as well. +func (m *bpfEndpointManager) extractTiers(tiers []*proto.TierInfo, direction PolDirection, endTierDrop bool) (rTiers []polprog.Tier) { dir := direction.RuleDir() - if tier == nil { - return - } - - directionalPols := tier.IngressPolicies - if direction == PolDirnEgress { - directionalPols = tier.EgressPolicies - } - - if len(directionalPols) > 0 { - polTier := polprog.Tier{ - Name: tier.Name, - Policies: make([]polprog.Policy, len(directionalPols)), + for _, tier := range tiers { + directionalPols := tier.IngressPolicies + if direction == PolDirnEgress { + directionalPols = tier.EgressPolicies } - for i, polName := range directionalPols { - pol := m.policies[proto.PolicyID{Tier: tier.Name, Name: polName}] - if pol == nil { - log.WithField("tier", tier).Warn("Tier refers to unknown policy!") - continue - } - var prules []*proto.Rule - if direction == PolDirnIngress { - prules = pol.InboundRules - } else { - prules = pol.OutboundRules - } - policy := polprog.Policy{ - Name: polName, - Rules: make([]polprog.Rule, len(prules)), + if len(directionalPols) > 0 { + + polTier := polprog.Tier{ + Name: tier.Name, + Policies: make([]polprog.Policy, len(directionalPols)), } - for ri, r := range prules { - policy.Rules[ri] = polprog.Rule{ - Rule: r, - MatchID: m.ruleMatchID(dir, r.Action, "Policy", polName, ri), + for i, polName := range directionalPols { + pol := m.policies[proto.PolicyID{Tier: tier.Name, Name: polName}] + if pol == nil { + log.WithField("tier", tier).Warn("Tier refers to unknown policy!") + continue + } + var prules []*proto.Rule + if direction == PolDirnIngress { + prules = pol.InboundRules + } else { + prules = pol.OutboundRules + } + policy := polprog.Policy{ + Name: polName, + Rules: make([]polprog.Rule, len(prules)), } + + for ri, r := range prules { + policy.Rules[ri] = polprog.Rule{ + Rule: r, + MatchID: m.ruleMatchID(dir, r.Action, "Policy", polName, ri), + } + } + + polTier.Policies[i] = policy } - polTier.Policies[i] = policy - } + if endTierDrop && tier.DefaultAction != string(apiv3.Pass) { + polTier.EndAction = polprog.TierEndDeny + } else { + polTier.EndAction = polprog.TierEndPass + } - if endTierDrop { - polTier.EndAction = polprog.TierEndDeny - } else { - polTier.EndAction = polprog.TierEndPass + rTiers = append(rTiers, polTier) } - - rTiers = append(rTiers, polTier) } return } @@ -2914,15 +3029,13 @@ func (m *bpfEndpointManager) extractProfiles(profileNames []string, direction Po return } -func (m *bpfEndpointManager) extractRules(tier *proto.TierInfo, profileNames []string, direction PolDirection) polprog.Rules { +func (m *bpfEndpointManager) extractRules(tiers []*proto.TierInfo, profileNames []string, direction PolDirection) polprog.Rules { var r polprog.Rules // When there is applicable normal policy that does not explicitly Allow or Deny traffic, // traffic is dropped. - r.Tiers = m.extractTiers(tier, direction, EndTierDrop) - + r.Tiers = m.extractTiers(tiers, direction, EndTierDrop) r.Profiles = m.extractProfiles(profileNames, direction) - return r } @@ -2944,18 +3057,15 @@ func (m *bpfEndpointManager) isL3Iface(iface string) bool { func (m *bpfEndpointManager) addWEPToIndexes(wlID proto.WorkloadEndpointID, wl *proto.WorkloadEndpoint) { for _, t := range wl.Tiers { - m.addPolicyToEPMappings(t.IngressPolicies, wlID) - m.addPolicyToEPMappings(t.EgressPolicies, wlID) + m.addPolicyToEPMappings(t.Name, t.IngressPolicies, wlID) + m.addPolicyToEPMappings(t.Name, t.EgressPolicies, wlID) } m.addProfileToEPMappings(wl.ProfileIds, wlID) } -func (m *bpfEndpointManager) addPolicyToEPMappings(polNames []string, id interface{}) { +func (m *bpfEndpointManager) addPolicyToEPMappings(tier string, polNames []string, id interface{}) { for _, pol := range polNames { - polID := proto.PolicyID{ - Tier: "default", - Name: pol, - } + polID := proto.PolicyID{Tier: tier, Name: pol} if m.policiesToWorkloads[polID] == nil { m.policiesToWorkloads[polID] = set.New[any]() } @@ -2981,8 +3091,8 @@ func (m *bpfEndpointManager) removeWEPFromIndexes(wlID proto.WorkloadEndpointID, } for _, t := range wep.Tiers { - m.removePolicyToEPMappings(t.IngressPolicies, wlID) - m.removePolicyToEPMappings(t.EgressPolicies, wlID) + m.removePolicyToEPMappings(t.Name, t.IngressPolicies, wlID) + m.removePolicyToEPMappings(t.Name, t.EgressPolicies, wlID) } m.removeProfileToEPMappings(wep.ProfileIds, wlID) @@ -2993,12 +3103,9 @@ func (m *bpfEndpointManager) removeWEPFromIndexes(wlID proto.WorkloadEndpointID, }) } -func (m *bpfEndpointManager) removePolicyToEPMappings(polNames []string, id interface{}) { +func (m *bpfEndpointManager) removePolicyToEPMappings(tier string, polNames []string, id interface{}) { for _, pol := range polNames { - polID := proto.PolicyID{ - Tier: "default", - Name: pol, - } + polID := proto.PolicyID{Tier: tier, Name: pol} polSet := m.policiesToWorkloads[polID] if polSet == nil { continue @@ -3084,6 +3191,7 @@ func (m *bpfEndpointManager) OnHEPUpdate(hostIfaceToEpMap map[string]proto.HostE delete(m.hostIfaceToEpMap, ifaceName) } m.dirtyIfaceNames.Add(ifaceName) + m.dirtyIfaceNames.AddSet(m.getBondSlaves(ifaceName)) } delete(hostIfaceToEpMap, ifaceName) } @@ -3098,14 +3206,15 @@ func (m *bpfEndpointManager) OnHEPUpdate(hostIfaceToEpMap map[string]proto.HostE m.addHEPToIndexes(ifaceName, &newEp) m.hostIfaceToEpMap[ifaceName] = newEp m.dirtyIfaceNames.Add(ifaceName) + m.dirtyIfaceNames.AddSet(m.getBondSlaves(ifaceName)) } } func (m *bpfEndpointManager) addHEPToIndexes(ifaceName string, ep *proto.HostEndpoint) { for _, tiers := range [][]*proto.TierInfo{ep.Tiers, ep.UntrackedTiers, ep.PreDnatTiers, ep.ForwardTiers} { for _, t := range tiers { - m.addPolicyToEPMappings(t.IngressPolicies, ifaceName) - m.addPolicyToEPMappings(t.EgressPolicies, ifaceName) + m.addPolicyToEPMappings(t.Name, t.IngressPolicies, ifaceName) + m.addPolicyToEPMappings(t.Name, t.EgressPolicies, ifaceName) } } m.addProfileToEPMappings(ep.ProfileIds, ifaceName) @@ -3114,8 +3223,8 @@ func (m *bpfEndpointManager) addHEPToIndexes(ifaceName string, ep *proto.HostEnd func (m *bpfEndpointManager) removeHEPFromIndexes(ifaceName string, ep *proto.HostEndpoint) { for _, tiers := range [][]*proto.TierInfo{ep.Tiers, ep.UntrackedTiers, ep.PreDnatTiers, ep.ForwardTiers} { for _, t := range tiers { - m.removePolicyToEPMappings(t.IngressPolicies, ifaceName) - m.removePolicyToEPMappings(t.EgressPolicies, ifaceName) + m.removePolicyToEPMappings(t.Name, t.IngressPolicies, ifaceName) + m.removePolicyToEPMappings(t.Name, t.EgressPolicies, ifaceName) } } @@ -3867,8 +3976,8 @@ func (m *bpfEndpointManager) onServiceUpdate(update *proto.ServiceUpdate) { }).Info("Service Update") ipstr := make([]string, 0, 2) - if update.ClusterIp != "" { - ipstr = append(ipstr, update.ClusterIp) + if len(update.ClusterIps) > 0 { + ipstr = append(ipstr, update.ClusterIps...) } if update.LoadbalancerIp != "" { ipstr = append(ipstr, update.LoadbalancerIp) @@ -3980,22 +4089,6 @@ func (m *bpfEndpointManager) delRoute(cidr ip.CIDR) { }).Debug("delRoute") } -func (m *bpfEndpointManager) GetRouteTableSyncers() []routetable.RouteTableSyncer { - if m.hostNetworkedNATMode == hostNetworkedNATDisabled { - return nil - } - - tables := []routetable.RouteTableSyncer{} - if m.v4 != nil { - tables = append(tables, m.routeTableV4) - } - if m.v6 != nil { - tables = append(tables, m.routeTableV6) - } - - return tables -} - // updatePolicyCache modifies entries in the cache, adding new entries and marking old entries dirty. func (m *bpfEndpointManager) updatePolicyCache(name string, owner string, inboundRules, outboundRules []*proto.Rule) { ruleIds := set.New[polprog.RuleMatchID]() @@ -4080,6 +4173,13 @@ func (m *bpfEndpointManager) getIfaceTypeFromLink(link netlink.Link) IfaceType { return IfaceTypeData } +func (m *bpfEndpointManager) getBondSlaves(masterIfName string) set.Set[string] { + if val, ok := m.hostIfaceToSlaveDevices[masterIfName]; ok { + return val + } + return set.New[string]() +} + func newJumpMapAlloc(entryPoints int) *jumpMapAlloc { a := &jumpMapAlloc{ max: entryPoints, diff --git a/felix/dataplane/linux/bpf_ep_mgr_test.go b/felix/dataplane/linux/bpf_ep_mgr_test.go index 2dc18cbab87..01ff31f8cb4 100644 --- a/felix/dataplane/linux/bpf_ep_mgr_test.go +++ b/felix/dataplane/linux/bpf_ep_mgr_test.go @@ -1,6 +1,6 @@ //go:build !windows -// Copyright (c) 2021-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -57,6 +57,7 @@ import ( "github.com/projectcalico/calico/felix/netlinkshim" mocknetlink "github.com/projectcalico/calico/felix/netlinkshim/mocknetlink" "github.com/projectcalico/calico/felix/proto" + "github.com/projectcalico/calico/felix/routetable" "github.com/projectcalico/calico/felix/rules" "github.com/projectcalico/calico/libcalico-go/lib/set" ) @@ -65,6 +66,7 @@ type mockDataplane struct { mutex sync.Mutex lastProgID int progs map[string]int + numAttaches map[string]int policy map[string]polprog.Rules routes map[ip.CIDR]struct{} netlinkShim netlinkshim.Interface @@ -83,6 +85,7 @@ func newMockDataplane() *mockDataplane { return &mockDataplane{ lastProgID: 5, progs: map[string]int{}, + numAttaches: map[string]int{}, policy: map[string]polprog.Rules{}, routes: map[ip.CIDR]struct{}{}, netlinkShim: netlinkShim, @@ -112,7 +115,12 @@ func (m *mockDataplane) loadDefaultPolicies() error { } func (m *mockDataplane) ensureProgramAttached(ap attachPoint) (qDiscInfo, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + var qdisc qDiscInfo + key := ap.IfaceName() + ":" + ap.HookName().String() + m.numAttaches[key] = m.numAttaches[key] + 1 return qdisc, nil } @@ -247,6 +255,12 @@ func (m *mockDataplane) programAttached(key string) bool { return m.progs[key] != 0 } +func (m *mockDataplane) numOfAttaches(key string) int { + m.mutex.Lock() + defer m.mutex.Unlock() + return m.numAttaches[key] +} + func (m *mockDataplane) setRoute(cidr ip.CIDR) { m.mutex.Lock() defer m.mutex.Unlock() @@ -397,20 +411,20 @@ var _ = Describe("BPF Endpoint Manager", func() { maps.CommonMaps = commonMaps rrConfigNormal = rules.Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, - KubeIPVSSupportEnabled: true, - WorkloadIfacePrefixes: []string{"cali", "tap"}, - VXLANPort: 4789, - VXLANVNI: 4096, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, + KubeIPVSSupportEnabled: true, + WorkloadIfacePrefixes: []string{"cali", "tap"}, + VXLANPort: 4789, + VXLANVNI: 4096, } ruleRenderer = rules.NewRenderer(rrConfigNormal) filterTableV4 = newMockTable("filter") @@ -451,7 +465,8 @@ var _ = Describe("BPF Endpoint Manager", func() { filterTableV6, nil, logutils.NewSummarizer("test"), - &environment.FakeFeatureDetector{}, + &routetable.DummyTable{}, // FIXME test the routes. + &routetable.DummyTable{}, // FIXME test the routes. nil, environment.NewFeatureDetector(nil).GetFeatures(), 1250, @@ -474,6 +489,25 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(name).To(Equal(vv.IfName())) } + getPolicyIdx := func(idx int, name, hook string) int { + k := ifstate.NewKey(uint32(idx)) + vb, err := ifStateMap.Get(k.AsBytes()) + if err != nil { + Fail(fmt.Sprintf("Ifstate does not have key %s", k), 1) + } + vv := ifstate.ValueFromBytes(vb) + Expect(name).To(Equal(vv.IfName())) + switch hook { + case "ingress": + return vv.IngressPolicyV4() + case "egress": + return vv.EgressPolicyV4() + case "xdp": + return vv.XDPPolicyV4() + } + return -1 + } + genIfaceUpdate := func(name string, state ifacemonitor.State, index int) func() { return func() { bpfEpMgr.OnUpdate(&ifaceStateUpdate{Name: name, State: state, Index: index}) @@ -544,12 +578,34 @@ var _ = Describe("BPF Endpoint Manager", func() { } } + genHostMetadataUpdate := func(ip string) func() { + return func() { + bpfEpMgr.OnUpdate(&proto.HostMetadataUpdate{ + Hostname: "uthost", + Ipv4Addr: ip, + }) + err := bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + } + } + + genHostMetadataV6Update := func(ip string) func() { + return func() { + bpfEpMgr.OnUpdate(&proto.HostMetadataV6Update{ + Hostname: "uthost", + Ipv6Addr: ip, + }) + err := bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + } + } + hostEp := proto.HostEndpoint{ Name: "uthost-eth0", PreDnatTiers: []*proto.TierInfo{ { Name: "default", - IngressPolicies: []string{"mypolicy"}, + IngressPolicies: []string{"default.mypolicy"}, }, }, } @@ -559,8 +615,8 @@ var _ = Describe("BPF Endpoint Manager", func() { Tiers: []*proto.TierInfo{ { Name: "default", - IngressPolicies: []string{"mypolicy"}, - EgressPolicies: []string{"mypolicy"}, + IngressPolicies: []string{"default.mypolicy"}, + EgressPolicies: []string{"default.mypolicy"}, }, }, } @@ -646,6 +702,34 @@ var _ = Describe("BPF Endpoint Manager", func() { }) }) + Context("with workload endpoints", func() { + JustBeforeEach(func() { + newBpfEpMgr(true) + genWLUpdate("cali12345")() + genIfaceUpdate("cali12345", ifacemonitor.StateUp, 15)() + }) + + It("must re-attach programs when hostIP changes", func() { + Expect(dp.programAttached("cali12345:ingress")).To(BeTrue()) + Expect(dp.programAttached("cali12345:egress")).To(BeTrue()) + Expect(dp.numOfAttaches("cali12345:ingress")).To(Equal(1)) + Expect(dp.numOfAttaches("cali12345:egress")).To(Equal(1)) + genHostMetadataUpdate("5.6.7.8/32")() + Expect(dp.numOfAttaches("cali12345:ingress")).To(Equal(2)) + Expect(dp.numOfAttaches("cali12345:egress")).To(Equal(2)) + genHostMetadataUpdate("1.2.3.4")() + Expect(dp.numOfAttaches("cali12345:ingress")).To(Equal(3)) + Expect(dp.numOfAttaches("cali12345:egress")).To(Equal(3)) + + genHostMetadataV6Update("1::5/128")() + Expect(dp.numOfAttaches("cali12345:ingress")).To(Equal(4)) + Expect(dp.numOfAttaches("cali12345:egress")).To(Equal(4)) + genHostMetadataV6Update("1::4")() + Expect(dp.numOfAttaches("cali12345:ingress")).To(Equal(5)) + Expect(dp.numOfAttaches("cali12345:egress")).To(Equal(5)) + }) + }) + Context("Ifacetype detection", func() { JustBeforeEach(func() { err := dp.createIface("vxlan0", 10, "vxlan") @@ -702,6 +786,13 @@ var _ = Describe("BPF Endpoint Manager", func() { Flags: net.FlagUp, }, nil } + if ifindex == 12 { + return &net.Interface{ + Name: "bond1", + Index: 12, + Flags: net.FlagUp, + }, nil + } return nil, errors.New("no such network interface") } @@ -724,6 +815,8 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(dp.programAttached("bond0:ingress")).To(BeTrue()) Expect(dp.programAttached("bond0:egress")).To(BeTrue()) checkIfState(10, "bond0", ifstate.FlgIPv4Ready|ifstate.FlgBond) + xdpID := getPolicyIdx(10, "bond0", "xdp") + Expect(xdpID).To(Equal(-1)) }) It("should not attach to bond slaves", func() { Expect(dp.programAttached("eth10:ingress")).To(BeFalse()) @@ -732,6 +825,34 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(dp.programAttached("eth20:egress")).To(BeFalse()) }) + It("should attach xdp to slave interfaces when the slave interface update is received first", func() { + err := dp.createBondSlaves("eth11", 21, 12) + Expect(err).NotTo(HaveOccurred()) + err = dp.createBondSlaves("eth21", 31, 12) + Expect(err).NotTo(HaveOccurred()) + err = dp.createIface("bond1", 12, "bond") + Expect(err).NotTo(HaveOccurred()) + + genIfaceUpdate("eth11", ifacemonitor.StateUp, 21)() + genIfaceUpdate("eth21", ifacemonitor.StateUp, 31)() + genIfaceUpdate("bond1", ifacemonitor.StateUp, 12)() + genUntracked("default", "untracked1")() + newHEP := hostEp + newHEP.UntrackedTiers = []*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"untracked1"}, + }} + genHEPUpdate("bond1", newHEP)() + err = bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + Expect(dp.programAttached("eth11:ingress")).To(BeFalse()) + Expect(dp.programAttached("eth11:egress")).To(BeFalse()) + Expect(dp.programAttached("eth21:ingress")).To(BeFalse()) + Expect(dp.programAttached("eth21:egress")).To(BeFalse()) + Expect(dp.programAttached("eth11:xdp")).To(BeTrue()) + Expect(dp.programAttached("eth21:xdp")).To(BeTrue()) + }) + It("should attach to interfaces when it is removed from bond", func() { err := dp.deleteIface("eth10") Expect(err).NotTo(HaveOccurred()) @@ -769,12 +890,46 @@ var _ = Describe("BPF Endpoint Manager", func() { genIfaceUpdate("eth11", ifacemonitor.StateNotPresent, 21)() genIfaceUpdate("foo0", ifacemonitor.StateNotPresent, 11)() }) + + It("should attach XDP to slave devices", func() { + By("adding untracked policy") + genUntracked("default", "untracked1")() + newHEP := hostEp + newHEP.UntrackedTiers = []*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"untracked1"}, + }} + genHEPUpdate("bond0", newHEP)() + err := bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + + Expect(dp.programAttached("bond0:ingress")).To(BeTrue()) + Expect(dp.programAttached("bond0:egress")).To(BeTrue()) + Expect(dp.programAttached("bond0:xdp")).To(BeFalse()) + checkIfState(10, "bond0", ifstate.FlgIPv4Ready|ifstate.FlgBond) + + Expect(dp.programAttached("eth10:ingress")).To(BeFalse()) + Expect(dp.programAttached("eth10:egress")).To(BeFalse()) + Expect(dp.programAttached("eth20:ingress")).To(BeFalse()) + Expect(dp.programAttached("eth20:egress")).To(BeFalse()) + Expect(dp.programAttached("eth10:xdp")).To(BeTrue()) + Expect(dp.programAttached("eth20:xdp")).To(BeTrue()) + + By("removing the untracked policy") + genHEPUpdate("bond0", hostEp)() + err = bpfEpMgr.CompleteDeferredWork() + Expect(err).NotTo(HaveOccurred()) + Expect(dp.programAttached("bond0:ingress")).To(BeTrue()) + Expect(dp.programAttached("bond0:egress")).To(BeTrue()) + Expect(dp.programAttached("eth10:xdp")).To(BeFalse()) + Expect(dp.programAttached("eth20:xdp")).To(BeFalse()) + }) }) }) Context("with eth0 up", func() { JustBeforeEach(func() { - genPolicy("default", "mypolicy")() + genPolicy("default", "default.mypolicy")() genIfaceUpdate("eth0", ifacemonitor.StateUp, 10)() }) @@ -853,7 +1008,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(bpfEpMgr.hostIfaceToEpMap["eth0"]).To(Equal(hostEp)) Expect(bpfEpMgr.policiesToWorkloads[proto.PolicyID{ Tier: "default", - Name: "mypolicy", + Name: "default.mypolicy", }]).To(HaveKey("eth0")) var eth0I, eth0E, eth0X *polprog.Rules @@ -903,7 +1058,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(bpfEpMgr.hostIfaceToEpMap["eth0"]).To(Equal(hostEp)) Expect(bpfEpMgr.policiesToWorkloads[proto.PolicyID{ Tier: "default", - Name: "mypolicy", + Name: "default.mypolicy", }]).To(HaveKey("eth0")) }) }) @@ -911,7 +1066,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Context("with eth0 host endpoint", func() { JustBeforeEach(func() { - genPolicy("default", "mypolicy")() + genPolicy("default", "default.mypolicy")() genHEPUpdate("eth0", hostEp)() }) @@ -922,7 +1077,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(bpfEpMgr.hostIfaceToEpMap["eth0"]).To(Equal(hostEp)) Expect(bpfEpMgr.policiesToWorkloads[proto.PolicyID{ Tier: "default", - Name: "mypolicy", + Name: "default.mypolicy", }]).To(HaveKey("eth0")) }) }) @@ -930,7 +1085,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Context("with host-* endpoint", func() { JustBeforeEach(func() { - genPolicy("default", "mypolicy")() + genPolicy("default", "default.mypolicy")() genHEPUpdate(allInterfaces, hostEp)() }) @@ -941,7 +1096,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(bpfEpMgr.hostIfaceToEpMap["eth0"]).To(Equal(hostEp)) Expect(bpfEpMgr.policiesToWorkloads[proto.PolicyID{ Tier: "default", - Name: "mypolicy", + Name: "default.mypolicy", }]).To(HaveKey("eth0")) }) @@ -952,7 +1107,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(bpfEpMgr.hostIfaceToEpMap).To(BeEmpty()) Expect(bpfEpMgr.policiesToWorkloads[proto.PolicyID{ Tier: "default", - Name: "mypolicy", + Name: "default.mypolicy", }]).NotTo(HaveKey("eth0")) }) }) @@ -963,7 +1118,7 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(bpfEpMgr.hostIfaceToEpMap).To(BeEmpty()) Expect(bpfEpMgr.policiesToWorkloads[proto.PolicyID{ Tier: "default", - Name: "mypolicy", + Name: "default.mypolicy", }]).NotTo(HaveKey("eth0")) }) }) @@ -1066,21 +1221,25 @@ var _ = Describe("BPF Endpoint Manager", func() { }) Describe("bpfnatip", func() { + JustBeforeEach(func() { + newBpfEpMgr(true) + }) It("should program the routes reflecting service state", func() { bpfEpMgr.OnUpdate(&proto.ServiceUpdate{ - Name: "service", - Namespace: "test", - ClusterIp: "1.2.3.4", + Name: "service", + Namespace: "test", + ClusterIps: []string{"1.2.3.4", "1::2"}, }) err := bpfEpMgr.CompleteDeferredWork() Expect(err).NotTo(HaveOccurred()) - Expect(dp.routes).To(HaveLen(1)) + Expect(dp.routes).To(HaveLen(2)) Expect(dp.routes).To(HaveKey(ip.MustParseCIDROrIP("1.2.3.4"))) + Expect(dp.routes).To(HaveKey(ip.MustParseCIDROrIP("1::2"))) bpfEpMgr.OnUpdate(&proto.ServiceUpdate{ Name: "service", Namespace: "test", - ClusterIp: "1.2.3.4", + ClusterIps: []string{"1.2.3.4"}, LoadbalancerIp: "5.6.7.8", }) err = bpfEpMgr.CompleteDeferredWork() @@ -1092,7 +1251,7 @@ var _ = Describe("BPF Endpoint Manager", func() { bpfEpMgr.OnUpdate(&proto.ServiceUpdate{ Name: "service", Namespace: "test", - ClusterIp: "1.2.3.4", + ClusterIps: []string{"1.2.3.4"}, LoadbalancerIp: "5.6.7.8", ExternalIps: []string{"1.0.0.1", "1.0.0.2"}, }) @@ -1103,9 +1262,9 @@ var _ = Describe("BPF Endpoint Manager", func() { Expect(dp.routes).To(HaveKey(ip.MustParseCIDROrIP("5.6.7.8"))) bpfEpMgr.OnUpdate(&proto.ServiceUpdate{ - Name: "service", - Namespace: "test", - ClusterIp: "1.2.3.4", + Name: "service", + Namespace: "test", + ClusterIps: []string{"1.2.3.4"}, }) err = bpfEpMgr.CompleteDeferredWork() Expect(err).NotTo(HaveOccurred()) @@ -1123,7 +1282,7 @@ var _ = Describe("BPF Endpoint Manager", func() { bpfEpMgr.OnUpdate(&proto.ServiceUpdate{ Name: "service", Namespace: "test", - ClusterIp: "1.2.3.4", + ClusterIps: []string{"1.2.3.4"}, LoadbalancerIp: "5.6.7.8", }) err = bpfEpMgr.CompleteDeferredWork() @@ -1252,6 +1411,9 @@ var _ = Describe("BPF Endpoint Manager", func() { } It("should reclaim indexes for active interfaces", func() { + bpfEpMgr.bpfLogLevel = "debug" + bpfEpMgr.logFilters = map[string]string{"all": "tcp"} + for i := 0; i < 8; i++ { _ = jumpMap.Update(jump.Key(i), jump.Value(uint32(1000+i))) _ = jumpMap.Update(jump.Key(i+jump.TCMaxEntryPoints), jump.Value(uint32(1000+i))) @@ -1293,17 +1455,17 @@ var _ = Describe("BPF Endpoint Manager", func() { 123: value123.String(), })) - // Expect clean-up deletions but no value changes due to mocking. - Expect(dumpJumpMap(jumpMap)).To(Equal(map[int]int{ - 0: 1000, - 2: 1002, - 3: 1003, - 4: 1004, - 10000: 1000, - 10002: 1002, - 10003: 1003, - 10004: 1004, - })) + // Expect clean-up deletions. + jmps := dumpJumpMap(jumpMap) + Expect(jmps).To(HaveLen(8)) + Expect(jmps).To(HaveKey(0)) /* filters reloaded to reflect current expressions */ + Expect(jmps).To(HaveKey(2)) + Expect(jmps).To(HaveKey(3)) + Expect(jmps).To(HaveKey(4)) + Expect(jmps).To(HaveKeyWithValue(10000, 1000)) + Expect(jmps).To(HaveKeyWithValue(10002, 1002)) + Expect(jmps).To(HaveKeyWithValue(10003, 1003)) + Expect(jmps).To(HaveKeyWithValue(10004, 1004)) Expect(dumpJumpMap(xdpJumpMap)).To(Equal(map[int]int{ 1: 2001, })) @@ -1622,6 +1784,9 @@ var _ = Describe("BPF Endpoint Manager", func() { newBpfEpMgr(true) }) It("should clean up jump map entries for missing interfaces", func() { + bpfEpMgr.bpfLogLevel = "debug" + bpfEpMgr.logFilters = map[string]string{"all": "tcp"} + for i := 0; i < 17; i++ { _ = jumpMap.Update(jump.Key(i), jump.Value(uint32(1000+i))) _ = jumpMap.Update(jump.Key(i+jump.TCMaxEntryPoints), jump.Value(uint32(1000+i))) @@ -1686,6 +1851,9 @@ var _ = Describe("BPF Endpoint Manager", func() { } It("should reclaim indexes for active interfaces", func() { + bpfEpMgr.bpfLogLevel = "debug" + bpfEpMgr.logFilters = map[string]string{"all": "tcp"} + for i := 0; i < 8; i++ { _ = jumpMap.Update(jump.Key(i), jump.Value(uint32(1000+i))) _ = jumpMap.Update(jump.Key(i+jump.TCMaxEntryPoints), jump.Value(uint32(1000+i))) @@ -1728,13 +1896,14 @@ var _ = Describe("BPF Endpoint Manager", func() { 123: value123.String(), })) - // Expect clean-up deletions but no value changes due to mocking. - Expect(dumpJumpMap(jumpMap)).To(Equal(map[int]int{ - 2: 1002, - 3: 1003, - 10002: 1002, - 10003: 1003, - })) + // Expect clean-up deletions. + jmps := dumpJumpMap(jumpMap) + Expect(jmps).To(HaveLen(5)) + Expect(jmps).To(HaveKey(2)) /* filters reloaded to reflect current expressions */ + Expect(jmps).To(HaveKey(3)) + Expect(jmps).To(HaveKey(4)) + Expect(jmps).To(HaveKeyWithValue(10002, 1002)) + Expect(jmps).To(HaveKeyWithValue(10003, 1003)) Expect(dumpJumpMap(xdpJumpMap)).To(Equal(map[int]int{ 1: 2001, })) diff --git a/felix/dataplane/linux/endpoint_mgr.go b/felix/dataplane/linux/endpoint_mgr.go index e39a4088302..f6d5551accd 100644 --- a/felix/dataplane/linux/endpoint_mgr.go +++ b/felix/dataplane/linux/endpoint_mgr.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,9 +23,10 @@ import ( "regexp" "strings" - apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" log "github.com/sirupsen/logrus" + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/felix/dataplane/common" "github.com/projectcalico/calico/felix/generictables" "github.com/projectcalico/calico/felix/ifacemonitor" @@ -131,7 +132,7 @@ type endpointManager struct { mangleTable Table filterTable Table ruleRenderer rules.RuleRenderer - routeTable routetable.RouteTableInterface + routeTable *routetable.ClassView writeProcSys procSysWriter osStat func(path string) (os.FileInfo, error) epMarkMapper rules.EndpointMarkMapper @@ -207,6 +208,7 @@ type endpointManager struct { callbacks endpointManagerCallbacks bpfEnabled bool bpfEndpointManager hepListener + bpfLogLevel string } type EndpointStatusUpdateCallback func(ipVersion uint8, id interface{}, status string) @@ -218,7 +220,7 @@ func newEndpointManager( mangleTable Table, filterTable Table, ruleRenderer rules.RuleRenderer, - routeTable routetable.RouteTableInterface, + routeTable routetable.Interface, ipVersion uint8, epMarkMapper rules.EndpointMarkMapper, kubeIPVSSupportEnabled bool, @@ -228,6 +230,7 @@ func newEndpointManager( bpfEnabled bool, bpfEndpointManager hepListener, callbacks *common.Callbacks, + bpfLogLevel string, floatingIPsEnabled bool, nft bool, ) *endpointManager { @@ -248,6 +251,7 @@ func newEndpointManager( bpfEnabled, bpfEndpointManager, callbacks, + bpfLogLevel, floatingIPsEnabled, nft, ) @@ -258,7 +262,7 @@ func newEndpointManagerWithShims( mangleTable Table, filterTable Table, ruleRenderer rules.RuleRenderer, - routeTable routetable.RouteTableInterface, + routeTable routetable.Interface, ipVersion uint8, epMarkMapper rules.EndpointMarkMapper, kubeIPVSSupportEnabled bool, @@ -270,6 +274,7 @@ func newEndpointManagerWithShims( bpfEnabled bool, bpfEndpointManager hepListener, callbacks *common.Callbacks, + bpfLogLevel string, floatingIPsEnabled bool, nft bool, ) *endpointManager { @@ -298,7 +303,7 @@ func newEndpointManagerWithShims( mangleTable: mangleTable, filterTable: filterTable, ruleRenderer: ruleRenderer, - routeTable: routeTable, + routeTable: routetable.NewClassView(routetable.RouteClassLocalWorkload, routeTable), writeProcSys: procSysWriter, osStat: osStat, epMarkMapper: epMarkMapper, @@ -350,6 +355,7 @@ func newEndpointManagerWithShims( OnEndpointStatusUpdate: onWorkloadEndpointStatusUpdate, callbacks: newEndpointManagerCallbacks(callbacks, ipVersion), + bpfLogLevel: bpfLogLevel, } } @@ -534,10 +540,6 @@ func (m *endpointManager) tiersUseDirtyPolicy(tiers []*proto.TierInfo) bool { return false } -func (m *endpointManager) GetRouteTableSyncers() []routetable.RouteTableSyncer { - return []routetable.RouteTableSyncer{m.routeTable} -} - func (m *endpointManager) markEndpointStatusDirtyByIface(ifaceName string) { logCxt := log.WithField("ifaceName", ifaceName) if epID, ok := m.activeWlIfaceNameToID[ifaceName]; ok { @@ -730,14 +732,9 @@ func (m *endpointManager) resolveWorkloadEndpoints() { m.wlIfaceNamesToReconfigure.Discard(oldWorkload.Name) delete(m.activeWlIfaceNameToID, oldWorkload.Name) } - var ingressPolicyNames, egressPolicyNames []string - if len(workload.Tiers) > 0 { - ingressPolicyNames = workload.Tiers[0].IngressPolicies - egressPolicyNames = workload.Tiers[0].EgressPolicies - } adminUp := workload.State == "active" if !m.bpfEnabled { - m.updateWorkloadEndpointChains(id, workload, ingressPolicyNames, egressPolicyNames, adminUp) + m.updateWorkloadEndpointChains(id, workload, adminUp) if len(workload.AllowSpoofedSourcePrefixes) > 0 && !m.hasSourceSpoofingConfiguration(workload.Name) { logCxt.Infof("Disabling RPF check for workload %s", workload.Name) @@ -864,26 +861,49 @@ func (m *endpointManager) resolveWorkloadEndpoints() { func (m *endpointManager) updateWorkloadEndpointChains( id proto.WorkloadEndpointID, workload *proto.WorkloadEndpoint, - ingressPolicyNames []string, - egressPolicyNames []string, adminUp bool, ) { - ingressGroups := m.groupPolicies("default", ingressPolicyNames, rules.PolicyDirectionInbound) - egressGroups := m.groupPolicies("default", egressPolicyNames, rules.PolicyDirectionOutbound) - m.updatePolicyGroups(workload.Name, append(ingressGroups, egressGroups...)) + tierGroups := m.groupTieredPolicy(workload.Tiers, includeInbound|includeOutbound) + m.updatePolicyGroups(workload.Name, tierGroups) chains := m.ruleRenderer.WorkloadEndpointToIptablesChains( workload.Name, m.epMarkMapper, adminUp, - ingressGroups, - egressGroups, + tierGroups, workload.ProfileIds, ) m.filterTable.UpdateChains(chains) m.activeWlIDToChains[id] = chains } +type tierGroupFilter int + +const ( + includeInbound tierGroupFilter = 1 << iota + includeOutbound +) + +func (m *endpointManager) groupTieredPolicy(tieredPolicies []*proto.TierInfo, filter tierGroupFilter) []rules.TierPolicyGroups { + var tierPolGroups []rules.TierPolicyGroups + for _, tierInfo := range tieredPolicies { + var inPols, outPols []*rules.PolicyGroup + if filter&includeInbound != 0 { + inPols = m.groupPolicies(tierInfo.Name, tierInfo.IngressPolicies, rules.PolicyDirectionInbound) + } + if filter&includeOutbound != 0 { + outPols = m.groupPolicies(tierInfo.Name, tierInfo.EgressPolicies, rules.PolicyDirectionOutbound) + } + tierPolGroups = append(tierPolGroups, rules.TierPolicyGroups{ + Name: tierInfo.Name, + DefaultAction: tierInfo.DefaultAction, + IngressPolicies: inPols, + EgressPolicies: outPols, + }) + } + return tierPolGroups +} + func wlIdsAscending(id1, id2 *proto.WorkloadEndpointID) bool { if id1.OrchestratorId == id2.OrchestratorId { // Need to compare WorkloadId. @@ -1104,8 +1124,8 @@ func (m *endpointManager) updateHostEndpoints() { } } - ifaceNameToPolicyGroups := map[string][]*rules.PolicyGroup{} - addPolicyGroups := func(ifaceName string, pgs []*rules.PolicyGroup) { + ifaceNameToPolicyGroups := map[string][]rules.TierPolicyGroups{} + addPolicyGroups := func(ifaceName string, pgs []rules.TierPolicyGroups) { ifaceNameToPolicyGroups[ifaceName] = append(ifaceNameToPolicyGroups[ifaceName], pgs...) } @@ -1118,33 +1138,16 @@ func (m *endpointManager) updateHostEndpoints() { hostEp := m.rawHostEndpoints[id] // Update chains in the filter and mangle tables, for normal traffic. - var ingressPolicyNames, egressPolicyNames []string - var ingressForwardPolicyNames, egressForwardPolicyNames []string - if len(hostEp.Tiers) > 0 { - ingressPolicyNames = hostEp.Tiers[0].IngressPolicies - egressPolicyNames = hostEp.Tiers[0].EgressPolicies - } - if len(hostEp.ForwardTiers) > 0 { - ingressForwardPolicyNames = hostEp.ForwardTiers[0].IngressPolicies - egressForwardPolicyNames = hostEp.ForwardTiers[0].EgressPolicies - } - - ingressGroups := m.groupPolicies("default", ingressPolicyNames, rules.PolicyDirectionInbound) - addPolicyGroups(ifaceName, ingressGroups) - egressGroups := m.groupPolicies("default", egressPolicyNames, rules.PolicyDirectionOutbound) - addPolicyGroups(ifaceName, egressGroups) - ingressForwardGroups := m.groupPolicies("default", ingressForwardPolicyNames, rules.PolicyDirectionInbound) - addPolicyGroups(ifaceName, ingressForwardGroups) - egressForwardGroups := m.groupPolicies("default", egressForwardPolicyNames, rules.PolicyDirectionOutbound) - addPolicyGroups(ifaceName, egressForwardGroups) + normalTierGroups := m.groupTieredPolicy(hostEp.Tiers, includeInbound|includeOutbound) + addPolicyGroups(ifaceName, normalTierGroups) + forwardTierGroups := m.groupTieredPolicy(hostEp.ForwardTiers, includeInbound|includeOutbound) + addPolicyGroups(ifaceName, forwardTierGroups) filtChains := m.ruleRenderer.HostEndpointToFilterChains( ifaceName, + normalTierGroups, + forwardTierGroups, m.epMarkMapper, - ingressGroups, - egressGroups, - ingressForwardGroups, - egressForwardGroups, hostEp.ProfileIds, ) @@ -1156,7 +1159,7 @@ func (m *endpointManager) updateHostEndpoints() { mangleChains := m.ruleRenderer.HostEndpointToMangleEgressChains( ifaceName, - egressGroups, + normalTierGroups, hostEp.ProfileIds, ) if !reflect.DeepEqual(mangleChains, m.activeHostIfaceToMangleEgressChains[ifaceName]) { @@ -1173,15 +1176,11 @@ func (m *endpointManager) updateHostEndpoints() { hostEp := m.rawHostEndpoints[id] // Update the mangle table for preDNAT policy. - var ingressPolicyNames []string - if len(hostEp.PreDnatTiers) > 0 { - ingressPolicyNames = hostEp.PreDnatTiers[0].IngressPolicies - } - ingressGroups := m.groupPolicies("default", ingressPolicyNames, rules.PolicyDirectionInbound) - addPolicyGroups(ifaceName, ingressGroups) + preDNATTierGroups := m.groupTieredPolicy(hostEp.PreDnatTiers, includeInbound) + addPolicyGroups(ifaceName, preDNATTierGroups) mangleChains := m.ruleRenderer.HostEndpointToMangleIngressChains( ifaceName, - ingressGroups, + preDNATTierGroups, ) if !reflect.DeepEqual(mangleChains, m.activeHostIfaceToMangleIngressChains[ifaceName]) { m.mangleTable.UpdateChains(mangleChains) @@ -1222,30 +1221,22 @@ func (m *endpointManager) updateHostEndpoints() { hostEp := m.rawHostEndpoints[id] // Update the raw chain, for untracked traffic. - var ingressPolicyNames, egressPolicyNames []string - if len(hostEp.UntrackedTiers) > 0 { - ingressPolicyNames = hostEp.UntrackedTiers[0].IngressPolicies - egressPolicyNames = hostEp.UntrackedTiers[0].EgressPolicies - } var rawChains []*generictables.Chain if m.bpfEnabled { - egressGroups := m.groupPolicies("default", egressPolicyNames, rules.PolicyDirectionOutbound) - addPolicyGroups(ifaceName, egressGroups) + untrackedTierGroups := m.groupTieredPolicy(hostEp.UntrackedTiers, includeOutbound) + addPolicyGroups(ifaceName, untrackedTierGroups) rawChains = append(rawChains, m.ruleRenderer.HostEndpointToRawEgressChain( ifaceName, - egressGroups, + untrackedTierGroups, )) } else { - ingressGroups := m.groupPolicies("default", ingressPolicyNames, rules.PolicyDirectionInbound) - addPolicyGroups(ifaceName, ingressGroups) - egressGroups := m.groupPolicies("default", egressPolicyNames, rules.PolicyDirectionOutbound) - addPolicyGroups(ifaceName, egressGroups) + untrackedTierGroups := m.groupTieredPolicy(hostEp.UntrackedTiers, includeInbound|includeOutbound) + addPolicyGroups(ifaceName, untrackedTierGroups) rawChains = m.ruleRenderer.HostEndpointToRawChains( ifaceName, - ingressGroups, - egressGroups, + untrackedTierGroups, ) } if !reflect.DeepEqual(rawChains, m.activeHostIfaceToRawChains[ifaceName]) { @@ -1378,6 +1369,7 @@ func (m *endpointManager) interfaceExistsInProcSys(name string) (bool, error) { func configureInterface(name string, ipVersion int, rpFilter string, writeProcSys procSysWriter) error { log.WithField("ifaceName", name).Info( "Applying /proc/sys configuration to interface.") + if ipVersion == 4 { // Enable routing to localhost. This is required to allow for NAT to the local // host. @@ -1533,6 +1525,13 @@ func (m *endpointManager) groupPolicies(tierName string, names []string, directi return groups } +func (m *endpointManager) increfTierGroups(tierGroups []rules.TierPolicyGroups) { + for _, tg := range tierGroups { + m.increfGroups(tg.IngressPolicies) + m.increfGroups(tg.EgressPolicies) + } +} + func (m *endpointManager) increfGroups(groups []*rules.PolicyGroup) { for _, group := range groups { if group.ShouldBeInlined() { @@ -1569,22 +1568,27 @@ func (m *endpointManager) decrefGroups(chainNames []string) { } } -func (m *endpointManager) updatePolicyGroups(ifaceName string, allGroups []*rules.PolicyGroup) { +func (m *endpointManager) updatePolicyGroups(ifaceName string, allGroups []rules.TierPolicyGroups) { log.WithFields(log.Fields{ "ifaceName": ifaceName, - "groups": rules.PolicyGroupSliceStringer(allGroups), + "groups": rules.TierPolicyGroupsStringer(allGroups), }).Debug("Updating policy groups for iface") oldChainNames := m.ifaceNameToPolicyGroupChainNames[ifaceName] // Incref first to avoid flapping. - m.increfGroups(allGroups) + m.increfTierGroups(allGroups) m.decrefGroups(oldChainNames) - if len(allGroups) > 0 { - newChainNames := make([]string, len(allGroups)) - for i, g := range allGroups { - newChainNames[i] = g.ChainName() + var newChainNames []string + for _, tg := range allGroups { + for _, groups := range [][]*rules.PolicyGroup{tg.IngressPolicies, tg.EgressPolicies} { + for _, group := range groups { + newChainNames = append(newChainNames, group.ChainName()) + } } + } + + if len(newChainNames) > 0 { m.ifaceNameToPolicyGroupChainNames[ifaceName] = newChainNames } else { delete(m.ifaceNameToPolicyGroupChainNames, ifaceName) diff --git a/felix/dataplane/linux/endpoint_mgr_test.go b/felix/dataplane/linux/endpoint_mgr_test.go index e3baa194454..c88da0668b4 100644 --- a/felix/dataplane/linux/endpoint_mgr_test.go +++ b/felix/dataplane/linux/endpoint_mgr_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -140,29 +140,37 @@ var wlEPID2 = proto.WorkloadEndpointID{ EndpointId: "endpoint-id-12", } -func hostChainsForIfaces(ifaceMetadata []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { - return append(chainsForIfaces(ifaceMetadata, epMarkMapper, true, "normal", false, iptables.AcceptAction{}), - chainsForIfaces(ifaceMetadata, epMarkMapper, true, "applyOnForward", false, iptables.AcceptAction{})..., +func hostChainsForIfaces(ipVersion uint8, ifaceTierNames []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { + return append(chainsForIfaces(ipVersion, ifaceTierNames, epMarkMapper, true, "normal", false, iptables.AcceptAction{}), + chainsForIfaces(ipVersion, ifaceTierNames, epMarkMapper, true, "applyOnForward", false, iptables.AcceptAction{})..., ) } -func mangleEgressChainsForIfaces(ifaceMetadata []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { - return chainsForIfaces(ifaceMetadata, epMarkMapper, true, "normal", true, iptables.SetMarkAction{Mark: 0x8}, iptables.ReturnAction{}) +func mangleEgressChainsForIfaces(ipVersion uint8, ifaceTierNames []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { + return chainsForIfaces(ipVersion, ifaceTierNames, epMarkMapper, true, "normal", true, iptables.SetMarkAction{Mark: 0x8}, iptables.ReturnAction{}) } -func rawChainsForIfaces(ifaceMetadata []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { - return chainsForIfaces(ifaceMetadata, epMarkMapper, true, "untracked", false, iptables.AcceptAction{}) +func rawChainsForIfaces(ipVersion uint8, ifaceTierNames []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { + return chainsForIfaces(ipVersion, ifaceTierNames, epMarkMapper, true, "untracked", false, iptables.AcceptAction{}) } -func preDNATChainsForIfaces(ifaceMetadata []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { - return chainsForIfaces(ifaceMetadata, epMarkMapper, true, "preDNAT", false, iptables.AcceptAction{}) +func preDNATChainsForIfaces(ipVersion uint8, ifaceTierNames []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { + return chainsForIfaces(ipVersion, ifaceTierNames, epMarkMapper, true, "preDNAT", false, iptables.AcceptAction{}) } -func wlChainsForIfaces(ifaceMetadata []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { - return chainsForIfaces(ifaceMetadata, epMarkMapper, false, "normal", false, iptables.AcceptAction{}) +func wlChainsForIfaces(ipVersion uint8, ifaceTierNames []string, epMarkMapper rules.EndpointMarkMapper) []*generictables.Chain { + return chainsForIfaces(ipVersion, ifaceTierNames, epMarkMapper, false, "normal", false, iptables.AcceptAction{}) } -func chainsForIfaces(ifaceMetadata []string, +func tierToPolicyName(tierName string) string { + if strings.HasPrefix(tierName, "tier") { + return "pol" + strings.TrimPrefix(tierName, "tier") + } + return "a" +} + +func chainsForIfaces(ipVersion uint8, + ifaceTierNames []string, epMarkMapper rules.EndpointMarkMapper, host bool, tableKind string, @@ -171,12 +179,13 @@ func chainsForIfaces(ifaceMetadata []string, ) []*generictables.Chain { const ( ProtoUDP = 17 + ProtoTCP = 6 ProtoIPIP = 4 VXLANPort = 4789 ) log.WithFields(log.Fields{ - "ifaces": ifaceMetadata, + "ifaces": ifaceTierNames, "host": host, "tableKind": tableKind, }).Debug("Calculating chains for interface") @@ -219,28 +228,40 @@ func chainsForIfaces(ifaceMetadata []string, inPrefix = "cali-from-" epmarkFromPrefix = inPrefix[:6] } - for _, ifaceMetadata := range ifaceMetadata { - var ifaceName, polName string - nameParts := strings.Split(ifaceMetadata, "_") + for _, ifaceTierName := range ifaceTierNames { + var ifaceName, tierName, polName string + nameParts := strings.Split(ifaceTierName, "_") ifaceKind := "normal" ingress := true egress := true if len(nameParts) == 1 { // Just an interface name "eth0", apply no tweaks. - log.Debug("Interface name only") ifaceName = nameParts[0] + tierName = "" polName = "" } else if len(nameParts) == 2 { - // Interface name and a policy name "eth0_polA". - log.Debug("Interface name and policy name") + // Interface name and a policy name "eth0_tierA". ifaceName = nameParts[0] - polName = nameParts[1] + if strings.HasPrefix(nameParts[1], "pol") { + tierName = "default" + polName = "/" + nameParts[1] + } else { + tierName = nameParts[1] + polName = "/" + tierToPolicyName(tierName) + } + ifaceKind = "normal" } else { // Interface name, policy name and untracked "eth0_polA_untracked" // or applyOnForward "eth0_polA_applyOnForward". log.Debug("Interface name policy name and untracked/ingress/egress") ifaceName = nameParts[0] - polName = nameParts[1] + if strings.HasPrefix(nameParts[1], "pol") { + tierName = "default" + polName = "/" + nameParts[1] + } else { + tierName = nameParts[1] + polName = "/" + tierToPolicyName(tierName) + } switch nameParts[2] { case "ingress": egress = false @@ -253,7 +274,7 @@ func chainsForIfaces(ifaceMetadata []string, epMark, err := epMarkMapper.GetEndpointMark(ifaceName) if err != nil { log.WithFields(log.Fields{ - "ifaces": ifaceMetadata, + "ifaces": ifaceTierNames, "host": host, "tableKind": tableKind, }).Debug("Failed to get endpoint mark for interface") @@ -289,15 +310,21 @@ func chainsForIfaces(ifaceMetadata []string, } outRules = append(outRules, generictables.Rule{ Match: iptables.Match(), - Action: iptables.ClearMarkAction{Mark: 0x18}, + Action: iptables.ClearMarkAction{Mark: 0x18}, // IptablesMarkAccept + IptablesMarkPass }) + if !host { outRules = append(outRules, dropEncapRules...) } - if egress && polName != "" && tableKind == ifaceKind { + if egress && polName != "" && tierName != "" && tableKind == ifaceKind { + outRules = append(outRules, generictables.Rule{ + Match: iptables.Match(), + Action: iptables.ClearMarkAction{Mark: 16}, + Comment: []string{"Start of tier " + tierName}, + }) outRules = append(outRules, generictables.Rule{ Match: iptables.Match().MarkClear(16), - Action: iptables.JumpAction{Target: "cali-po-" + polName}, + Action: iptables.JumpAction{Target: "cali-po-" + tierName + polName}, }) if tableKind == "untracked" { outRules = append(outRules, generictables.Rule{ @@ -314,11 +341,13 @@ func chainsForIfaces(ifaceMetadata []string, // Only end with a drop rule in the filter chain. In the raw chain, // we consider the policy as unfinished, because some of the // policy may live in the filter chain. - outRules = append(outRules, generictables.Rule{ - Match: iptables.Match().MarkClear(16), - Action: iptables.DropAction{}, - Comment: []string{"Drop if no policies passed packet"}, - }) + outRules = append(outRules, []generictables.Rule{ + { + Match: iptables.Match().MarkClear(16), + Action: iptables.DropAction{}, + Comment: []string{"Drop if no policies passed packet"}, + }, + }...) } } else if tableKind == "applyOnForward" { @@ -337,11 +366,13 @@ func chainsForIfaces(ifaceMetadata []string, } if tableKind == "normal" { - outRules = append(outRules, generictables.Rule{ - Match: iptables.Match(), - Action: iptables.DropAction{}, - Comment: []string{"Drop if no profiles matched"}, - }) + outRules = append(outRules, []generictables.Rule{ + { + Match: iptables.Match(), + Action: iptables.DropAction{}, + Comment: []string{"Drop if no profiles matched"}, + }, + }...) } inRules := []generictables.Rule{} @@ -369,13 +400,19 @@ func chainsForIfaces(ifaceMetadata []string, } inRules = append(inRules, generictables.Rule{ Match: iptables.Match(), - Action: iptables.ClearMarkAction{Mark: 0x18}, + Action: iptables.ClearMarkAction{Mark: 0x18}, // IptablesMarkAccept + IptablesMarkPass }) - if ingress && polName != "" && tableKind == ifaceKind { + + if ingress && tierName != "" && tableKind == ifaceKind { + inRules = append(inRules, generictables.Rule{ + Match: iptables.Match(), + Action: iptables.ClearMarkAction{Mark: 16}, + Comment: []string{"Start of tier " + tierName}, + }) // For untracked policy, we expect a tier with a policy in it. inRules = append(inRules, generictables.Rule{ Match: iptables.Match().MarkClear(16), - Action: iptables.JumpAction{Target: "cali-pi-" + polName}, + Action: iptables.JumpAction{Target: "cali-pi-" + tierName + polName}, }) if tableKind == "untracked" { inRules = append(inRules, generictables.Rule{ @@ -392,11 +429,13 @@ func chainsForIfaces(ifaceMetadata []string, // Only end with a drop rule in the filter chain. In the raw chain, // we consider the policy as unfinished, because some of the // policy may live in the filter chain. - inRules = append(inRules, generictables.Rule{ - Match: iptables.Match().MarkClear(16), - Action: iptables.DropAction{}, - Comment: []string{"Drop if no policies passed packet"}, - }) + inRules = append(inRules, []generictables.Rule{ + { + Match: iptables.Match().MarkClear(16), + Action: iptables.DropAction{}, + Comment: []string{"Drop if no policies passed packet"}, + }, + }...) } } else if tableKind == "applyOnForward" { @@ -415,11 +454,14 @@ func chainsForIfaces(ifaceMetadata []string, } if tableKind == "normal" { - inRules = append(inRules, generictables.Rule{ - Match: iptables.Match(), - Action: iptables.DropAction{}, - Comment: []string{"Drop if no profiles matched"}, - }) + dropComment := "Drop if no profiles matched" + inRules = append(inRules, []generictables.Rule{ + { + Match: iptables.Match(), + Action: iptables.DropAction{}, + Comment: []string{dropComment}, + }, + }...) } if tableKind == "preDNAT" { @@ -501,8 +543,8 @@ func chainsForIfaces(ifaceMetadata []string, }, ) } - } + if !host { dispatchOut = append(dispatchOut, generictables.Rule{ @@ -594,31 +636,45 @@ func chainsForIfaces(ifaceMetadata []string, } type mockRouteTable struct { + index int + kernelRoutes map[string][]routetable.Target currentRoutes map[string][]routetable.Target } -func (t *mockRouteTable) SetRoutes(ifaceName string, targets []routetable.Target) { +func (t *mockRouteTable) SetRoutes(routeClass routetable.RouteClass, ifaceName string, targets []routetable.Target) { log.WithFields(log.Fields{ + "index": t.index, "ifaceName": ifaceName, "targets": targets, }).Debug("SetRoutes") t.currentRoutes[ifaceName] = targets } -func (t *mockRouteTable) RouteRemove(_ string, _ ip.CIDR) { +func (t *mockRouteTable) RouteRemove(routeClass routetable.RouteClass, ifaceName string, cidr ip.CIDR) { } -func (t *mockRouteTable) RouteUpdate(_ string, _ routetable.Target) { +func (t *mockRouteTable) RouteUpdate(routeClass routetable.RouteClass, ifaceName string, target routetable.Target) { +} + +func (t *mockRouteTable) OnIfaceStateChanged(string, int, ifacemonitor.State) {} +func (t *mockRouteTable) QueueResync() {} +func (t *mockRouteTable) QueueResyncIface(ifaceName string) {} + +func (t *mockRouteTable) Index() int { + return t.index +} + +func (t *mockRouteTable) ReadRoutesFromKernel(ifaceName string) ([]routetable.Target, error) { + // TODO implement me + panic("implement me") } -func (t *mockRouteTable) OnIfaceStateChanged(string, ifacemonitor.State) {} -func (t *mockRouteTable) QueueResync() {} func (t *mockRouteTable) Apply() error { return nil } func (t *mockRouteTable) checkRoutes(ifaceName string, expected []routetable.Target) { - Expect(t.currentRoutes[ifaceName]).To(Equal(expected)) + Expect(t.currentRoutes[ifaceName]).To(ConsistOf(expected), "Expect route to exist in table %d. Current routes = %v", t.index, t.currentRoutes) } type statusReportRecorder struct { @@ -643,7 +699,7 @@ type hostEpSpec struct { name string ipv4Addrs []string ipv6Addrs []string - polName string + tierName string } func applyUpdates(epMgr *endpointManager) { @@ -677,20 +733,20 @@ func endpointManagerTests(ipVersion uint8) func() { BeforeEach(func() { rrConfigNormal = rules.Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, - KubeIPVSSupportEnabled: true, - WorkloadIfacePrefixes: []string{"cali", "tap"}, - VXLANPort: 4789, - VXLANVNI: 4096, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, + KubeIPVSSupportEnabled: true, + WorkloadIfacePrefixes: []string{"cali", "tap"}, + VXLANPort: 4789, + VXLANVNI: 4096, } eth0Addrs = set.New[string]() eth0Addrs.Add(ipv4) @@ -708,6 +764,7 @@ func endpointManagerTests(ipVersion uint8) func() { mangleTable = newMockTable("mangle") filterTable = newMockTable("filter") routeTable = &mockRouteTable{ + index: 0, currentRoutes: map[string][]routetable.Target{}, } mockProcSys = &testProcSys{state: map[string]string{}, pathsThatExist: map[string]bool{}} @@ -720,7 +777,7 @@ func endpointManagerTests(ipVersion uint8) func() { renderer, routeTable, ipVersion, - rules.NewEndpointMarkMapper(rrConfigNormal.IptablesMarkEndpoint, rrConfigNormal.IptablesMarkNonCaliEndpoint), + rules.NewEndpointMarkMapper(rrConfigNormal.MarkEndpoint, rrConfigNormal.MarkNonCaliEndpoint), rrConfigNormal.KubeIPVSSupportEnabled, []string{"cali"}, statusReportRec.endpointStatusUpdateCallback, @@ -730,6 +787,7 @@ func endpointManagerTests(ipVersion uint8) func() { false, hepListener, common.NewCallbacks(), + "info", true, false, ) @@ -744,24 +802,47 @@ func endpointManagerTests(ipVersion uint8) func() { untrackedTiers := []*proto.TierInfo{} preDNATTiers := []*proto.TierInfo{} forwardTiers := []*proto.TierInfo{} - if spec.polName != "" { - parts := strings.Split(spec.polName, "_") + if spec.tierName != "" { + parts := strings.Split(spec.tierName, "_") + var tierName string + var policies []string if len(parts) == 1 { + if strings.HasPrefix(parts[0], "pol") { + tierName = "default" + policies = []string{parts[0]} + } else { + tierName = parts[0] + policies = []string{tierToPolicyName(tierName)} + } tiers = append(tiers, &proto.TierInfo{ - Name: "default", - IngressPolicies: []string{spec.polName}, - EgressPolicies: []string{spec.polName}, + Name: tierName, + IngressPolicies: policies, + EgressPolicies: policies, }) } else if len(parts) == 2 && parts[1] == "untracked" { + if strings.HasPrefix(parts[0], "pol") { + tierName = "default" + policies = []string{parts[0]} + } else { + tierName = parts[0] + policies = []string{tierToPolicyName(tierName)} + } untrackedTiers = append(untrackedTiers, &proto.TierInfo{ - Name: "default", - IngressPolicies: []string{parts[0]}, - EgressPolicies: []string{parts[0]}, + Name: tierName, + IngressPolicies: policies, + EgressPolicies: policies, }) } else if len(parts) == 2 && parts[1] == "preDNAT" { + if strings.HasPrefix(parts[0], "pol") { + tierName = "default" + policies = []string{parts[0]} + } else { + tierName = parts[0] + policies = []string{tierToPolicyName(tierName)} + } preDNATTiers = append(preDNATTiers, &proto.TierInfo{ - Name: "default", - IngressPolicies: []string{parts[0]}, + Name: tierName, + IngressPolicies: policies, }) } else if len(parts) == 2 && parts[1] == "applyOnForward" { forwardTiers = append(forwardTiers, &proto.TierInfo{ @@ -770,17 +851,31 @@ func endpointManagerTests(ipVersion uint8) func() { EgressPolicies: []string{parts[0]}, }) } else if len(parts) == 2 && parts[1] == "ingress" { + if strings.HasPrefix(parts[0], "pol") { + tierName = "default" + policies = []string{parts[0]} + } else { + tierName = parts[0] + policies = []string{tierToPolicyName(tierName)} + } tiers = append(tiers, &proto.TierInfo{ - Name: "default", - IngressPolicies: []string{parts[0]}, + Name: tierName, + IngressPolicies: policies, }) } else if len(parts) == 2 && parts[1] == "egress" { + if strings.HasPrefix(parts[0], "pol") { + tierName = "default" + policies = []string{parts[0]} + } else { + tierName = parts[0] + policies = []string{tierToPolicyName(tierName)} + } tiers = append(tiers, &proto.TierInfo{ - Name: "default", - EgressPolicies: []string{parts[0]}, + Name: tierName, + EgressPolicies: policies, }) } else { - panic("Failed to parse policy name " + spec.polName) + panic("Failed to parse policy name " + spec.tierName) } } return func() { @@ -803,23 +898,23 @@ func endpointManagerTests(ipVersion uint8) func() { } } - expectChainsFor := func(names ...string) func() { + expectChainsFor := func(ipVersion uint8, names ...string) func() { return func() { filterTable.checkChains([][]*generictables.Chain{ wlDispatchEmpty, - hostChainsForIfaces(names, epMgr.epMarkMapper), + hostChainsForIfaces(ipVersion, names, epMgr.epMarkMapper), }) rawTable.checkChains([][]*generictables.Chain{ - rawChainsForIfaces(names, epMgr.epMarkMapper), + rawChainsForIfaces(ipVersion, names, epMgr.epMarkMapper), }) mangleTable.checkChains([][]*generictables.Chain{ - preDNATChainsForIfaces(names, epMgr.epMarkMapper), - mangleEgressChainsForIfaces(names, epMgr.epMarkMapper), + preDNATChainsForIfaces(ipVersion, names, epMgr.epMarkMapper), + mangleEgressChainsForIfaces(ipVersion, names, epMgr.epMarkMapper), }) } } - expectEmptyChains := func() func() { + expectEmptyChains := func(ipVersion uint8) func() { return func() { filterTable.checkChains([][]*generictables.Chain{ wlDispatchEmpty, @@ -872,16 +967,16 @@ func endpointManagerTests(ipVersion uint8) func() { applyUpdates(epMgr) }) - It("should have empty dispatch chains", expectEmptyChains()) + It("should have empty dispatch chains", expectEmptyChains(ipVersion)) It("should make no status reports", func() { Expect(statusReportRec.currentState).To(BeEmpty()) }) Describe("with * host endpoint", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "*", - polName: "polA", + id: "id1", + name: "*", + tierName: "polA", })) It("should report id1 up", func() { @@ -903,11 +998,11 @@ func endpointManagerTests(ipVersion uint8) func() { // we expect the one used to be the one with the alphabetically earliest ID. Describe("with host endpoint with tier matching eth0", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA", + id: "id1", + name: "eth0", + tierName: "tierA", })) - It("should have expected chains", expectChainsFor("eth0_polA")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierA")) It("should report id1 up", func() { Expect(statusReportRec.currentState).To(Equal(map[interface{}]string{ proto.HostEndpointID{EndpointId: "id1"}: "up", @@ -924,9 +1019,9 @@ func endpointManagerTests(ipVersion uint8) func() { JustBeforeEach(configureHostEp(&hostEpSpec{ id: "id2", ipv4Addrs: []string{ipv4}, - polName: "polB", + tierName: "tierB", })) - It("should have expected chains", expectChainsFor("eth0_polA")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierA")) It("should report id1 up, but id2 now in error", func() { Expect(statusReportRec.currentState).To(Equal(map[interface{}]string{ proto.HostEndpointID{EndpointId: "id1"}: "up", @@ -942,7 +1037,7 @@ func endpointManagerTests(ipVersion uint8) func() { Context("with the first host ep removed", func() { JustBeforeEach(removeHostEp("id1")) - It("should have expected chains", expectChainsFor("eth0_polB")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierB")) It("should report id2 up only", func() { Expect(statusReportRec.currentState).To(Equal(map[interface{}]string{ proto.HostEndpointID{EndpointId: "id2"}: "up", @@ -957,7 +1052,7 @@ func endpointManagerTests(ipVersion uint8) func() { Context("with both host eps removed", func() { JustBeforeEach(removeHostEp("id2")) - It("should have empty dispatch chains", expectEmptyChains()) + It("should have empty dispatch chains", expectEmptyChains(ipVersion)) It("should define host endpoints", func() { Expect(hepListener.state).To(BeEmpty()) @@ -970,9 +1065,9 @@ func endpointManagerTests(ipVersion uint8) func() { JustBeforeEach(configureHostEp(&hostEpSpec{ id: "id0", ipv4Addrs: []string{ipv4}, - polName: "polB", + tierName: "tierB", })) - It("should have expected chains", expectChainsFor("eth0_polB")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierB")) It("should report id0 up, but id1 now in error", func() { Expect(statusReportRec.currentState).To(Equal(map[interface{}]string{ proto.HostEndpointID{EndpointId: "id0"}: "up", @@ -988,7 +1083,7 @@ func endpointManagerTests(ipVersion uint8) func() { Context("with the first host ep removed", func() { JustBeforeEach(removeHostEp("id1")) - It("should have expected chains", expectChainsFor("eth0_polB")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierB")) It("should report id0 up only", func() { Expect(statusReportRec.currentState).To(Equal(map[interface{}]string{ proto.HostEndpointID{EndpointId: "id0"}: "up", @@ -1003,7 +1098,7 @@ func endpointManagerTests(ipVersion uint8) func() { Context("with both host eps removed", func() { JustBeforeEach(removeHostEp("id0")) - It("should have empty dispatch chains", expectEmptyChains()) + It("should have empty dispatch chains", expectEmptyChains(ipVersion)) It("should remove all status reports", func() { Expect(statusReportRec.currentState).To(BeEmpty()) @@ -1018,11 +1113,11 @@ func endpointManagerTests(ipVersion uint8) func() { Describe("replaced with untracked version", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA_untracked", + id: "id1", + name: "eth0", + tierName: "tierA_untracked", })) - It("should have expected chains", expectChainsFor("eth0_polA_untracked")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierA_untracked")) It("should define host endpoints", func() { Expect(hepListener.state).To(Equal(map[string]string{ @@ -1033,11 +1128,11 @@ func endpointManagerTests(ipVersion uint8) func() { Describe("replaced with applyOnForward version", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA_applyOnForward", + id: "id1", + name: "eth0", + tierName: "polA_applyOnForward", })) - It("should have expected chains", expectChainsFor("eth0_polA_applyOnForward")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_polA_applyOnForward")) It("should define host endpoints", func() { Expect(hepListener.state).To(Equal(map[string]string{ @@ -1048,11 +1143,11 @@ func endpointManagerTests(ipVersion uint8) func() { Describe("replaced with pre-DNAT version", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA_preDNAT", + id: "id1", + name: "eth0", + tierName: "polA_preDNAT", })) - It("should have expected chains", expectChainsFor("eth0_polA_preDNAT")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_polA_preDNAT")) It("should define host endpoints", func() { Expect(hepListener.state).To(Equal(map[string]string{ @@ -1063,11 +1158,11 @@ func endpointManagerTests(ipVersion uint8) func() { Describe("replaced with ingress-only version", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA_ingress", + id: "id1", + name: "eth0", + tierName: "polA_ingress", })) - It("should have expected chains", expectChainsFor("eth0_polA_ingress")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_polA_ingress")) It("should define host endpoints", func() { Expect(hepListener.state).To(Equal(map[string]string{ @@ -1078,11 +1173,11 @@ func endpointManagerTests(ipVersion uint8) func() { Describe("replaced with egress-only version", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA_egress", + id: "id1", + name: "eth0", + tierName: "polA_egress", })) - It("should have expected chains", expectChainsFor("eth0_polA_egress")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_polA_egress")) It("should define host endpoints", func() { Expect(hepListener.state).To(Equal(map[string]string{ @@ -1094,39 +1189,39 @@ func endpointManagerTests(ipVersion uint8) func() { Describe("with host endpoint with untracked tier matching eth0", func() { JustBeforeEach(configureHostEp(&hostEpSpec{ - id: "id1", - name: "eth0", - polName: "polA_untracked", + id: "id1", + name: "eth0", + tierName: "tierA_untracked", })) - It("should have expected chains", expectChainsFor("eth0_polA_untracked")) + It("should have expected chains", expectChainsFor(ipVersion, "eth0_tierA_untracked")) Context("with another host ep ( 0 { + d.dataplaneNeedsSync = true + } + // And publish and status updates. d.endpointStatusCombiner.Apply() @@ -2431,7 +2475,8 @@ func (d dummyLock) Lock() { func (d dummyLock) Unlock() { } -func startBPFDataplaneComponents(ipFamily proto.IPVersion, +func startBPFDataplaneComponents( + ipFamily proto.IPVersion, bpfmaps *bpfmap.IPMaps, ipSetIDAllocator *idalloc.IDAllocator, config Config, diff --git a/felix/dataplane/linux/int_dataplane_test.go b/felix/dataplane/linux/int_dataplane_test.go index d988af15f98..febc8b786b2 100644 --- a/felix/dataplane/linux/int_dataplane_test.go +++ b/felix/dataplane/linux/int_dataplane_test.go @@ -68,19 +68,19 @@ var _ = Describe("Constructor test", func() { OpenStackMetadataIP: net.ParseIP(configParams.MetadataAddr), OpenStackMetadataPort: uint16(configParams.MetadataPort), - IptablesMarkAccept: 0x1000000, - IptablesMarkPass: 0x2000000, - IptablesMarkScratch0: 0x4000000, - IptablesMarkScratch1: 0x8000000, - IptablesMarkEndpoint: 0x000ff00, + MarkAccept: 0x1000000, + MarkPass: 0x2000000, + MarkScratch0: 0x4000000, + MarkScratch1: 0x8000000, + MarkEndpoint: 0x000ff00, IPIPEnabled: configParams.Encapsulation.IPIPEnabled, IPIPTunnelAddress: configParams.IpInIpTunnelAddr, - EndpointToHostAction: configParams.DefaultEndpointToHostAction, - IptablesFilterAllowAction: configParams.IptablesFilterAllowAction, - IptablesMangleAllowAction: configParams.IptablesMangleAllowAction, - IptablesFilterDenyAction: configParams.IptablesFilterDenyAction, + EndpointToHostAction: configParams.DefaultEndpointToHostAction, + FilterAllowAction: configParams.IptablesFilterAllowAction, + MangleAllowAction: configParams.IptablesMangleAllowAction, + FilterDenyAction: configParams.IptablesFilterDenyAction, }, IPIPMTU: configParams.IpInIpMtu, HealthAggregator: healthAggregator, diff --git a/felix/dataplane/linux/ipip_mgr_netlink.go b/felix/dataplane/linux/ipip_mgr_netlink.go index 5daeea3a871..6c7a6a0bc99 100644 --- a/felix/dataplane/linux/ipip_mgr_netlink.go +++ b/felix/dataplane/linux/ipip_mgr_netlink.go @@ -15,9 +15,11 @@ package intdataplane import ( + "errors" "os/exec" "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" ) // ipipDataplane is a shim interface for mocking netlink and os/exec in the IPIP manager. @@ -45,7 +47,15 @@ func (r realIPIPNetlink) LinkSetUp(link netlink.Link) error { } func (r realIPIPNetlink) AddrList(link netlink.Link, family int) ([]netlink.Addr, error) { - return netlink.AddrList(link, family) + retries := 3 + for { + addrs, err := netlink.AddrList(link, family) + if errors.Is(err, unix.EINTR) && retries > 0 { + retries-- + continue + } + return addrs, err + } } func (r realIPIPNetlink) AddrAdd(link netlink.Link, addr *netlink.Addr) error { diff --git a/felix/dataplane/linux/masq_mgr_test.go b/felix/dataplane/linux/masq_mgr_test.go index 460923ef424..75ac7553700 100644 --- a/felix/dataplane/linux/masq_mgr_test.go +++ b/felix/dataplane/linux/masq_mgr_test.go @@ -45,11 +45,11 @@ var _ = Describe("Masquerade manager", func() { nil, nil, ), - IptablesMarkPass: 0x1, - IptablesMarkAccept: 0x2, - IptablesMarkScratch0: 0x4, - IptablesMarkScratch1: 0x8, - IptablesMarkEndpoint: 0x11110000, + MarkPass: 0x1, + MarkAccept: 0x2, + MarkScratch0: 0x4, + MarkScratch1: 0x8, + MarkEndpoint: 0x11110000, }) masqMgr = newMasqManager(ipSets, natTable, ruleRenderer, 1024, 4) }) diff --git a/felix/dataplane/linux/policy_mgr_test.go b/felix/dataplane/linux/policy_mgr_test.go index 7351c26ddc0..6b715913004 100644 --- a/felix/dataplane/linux/policy_mgr_test.go +++ b/felix/dataplane/linux/policy_mgr_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ var _ = Describe("Policy manager", func() { Describe("after a policy update", func() { BeforeEach(func() { policyMgr.OnUpdate(&proto.ActivePolicyUpdate{ - Id: &proto.PolicyID{Name: "pol1", Tier: "default"}, + Id: &proto.PolicyID{Name: "pol1", Tier: "tier1"}, Policy: &proto.Policy{ InboundRules: []*proto.Rule{ {Action: "deny"}, @@ -68,19 +68,19 @@ var _ = Describe("Policy manager", func() { It("should install the in and out chain", func() { filterTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) mangleTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) Describe("after a policy remove", func() { BeforeEach(func() { policyMgr.OnUpdate(&proto.ActivePolicyRemove{ - Id: &proto.PolicyID{Name: "pol1", Tier: "default"}, + Id: &proto.PolicyID{Name: "pol1", Tier: "tier1"}, }) }) @@ -94,7 +94,7 @@ var _ = Describe("Policy manager", func() { Describe("after an untracked policy update", func() { BeforeEach(func() { policyMgr.OnUpdate(&proto.ActivePolicyUpdate{ - Id: &proto.PolicyID{Name: "pol1", Tier: "default"}, + Id: &proto.PolicyID{Name: "pol1", Tier: "tier1"}, Policy: &proto.Policy{ InboundRules: []*proto.Rule{ {Action: "deny"}, @@ -111,27 +111,27 @@ var _ = Describe("Policy manager", func() { It("should install the raw chains", func() { rawTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) It("should install to the filter table", func() { filterTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) It("should install to the mangle table", func() { mangleTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) Describe("after a policy remove", func() { BeforeEach(func() { policyMgr.OnUpdate(&proto.ActivePolicyRemove{ - Id: &proto.PolicyID{Name: "pol1", Tier: "default"}, + Id: &proto.PolicyID{Name: "pol1", Tier: "tier1"}, }) }) @@ -150,7 +150,7 @@ var _ = Describe("Policy manager", func() { Describe("after a pre-DNAT policy update", func() { BeforeEach(func() { policyMgr.OnUpdate(&proto.ActivePolicyUpdate{ - Id: &proto.PolicyID{Name: "pol1", Tier: "default"}, + Id: &proto.PolicyID{Name: "pol1", Tier: "tier1"}, Policy: &proto.Policy{ InboundRules: []*proto.Rule{ {Action: "deny"}, @@ -167,27 +167,27 @@ var _ = Describe("Policy manager", func() { It("should install the raw chains", func() { rawTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) It("should install to the filter table", func() { filterTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) It("should install to the mangle table", func() { mangleTable.checkChains([][]*generictables.Chain{{ - {Name: "cali-pi-pol1"}, - {Name: "cali-po-pol1"}, + {Name: "cali-pi-tier1/pol1"}, + {Name: "cali-po-tier1/pol1"}, }}) }) Describe("after a policy remove", func() { BeforeEach(func() { policyMgr.OnUpdate(&proto.ActivePolicyRemove{ - Id: &proto.PolicyID{Name: "pol1", Tier: "default"}, + Id: &proto.PolicyID{Name: "pol1", Tier: "tier1"}, }) }) @@ -261,14 +261,14 @@ var _ = Describe("Raw egress policy manager", func() { numCallbackCalls = 0 rawTable = newMockTable("raw") ruleRenderer := rules.NewRenderer(rules.Config{ - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, }) policyMgr = newRawEgressPolicyManager( rawTable, diff --git a/felix/dataplane/linux/vxlan_mgr.go b/felix/dataplane/linux/vxlan_mgr.go index 77e2a9060fa..aeab8c0ce3a 100644 --- a/felix/dataplane/linux/vxlan_mgr.go +++ b/felix/dataplane/linux/vxlan_mgr.go @@ -16,12 +16,9 @@ package intdataplane import ( "context" - "errors" "fmt" "net" "reflect" - "regexp" - "sort" "strings" "sync" "syscall" @@ -29,20 +26,18 @@ import ( "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" - "golang.org/x/sys/unix" dpsets "github.com/projectcalico/calico/felix/dataplane/ipsets" "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs" - "github.com/projectcalico/calico/felix/environment" "github.com/projectcalico/calico/felix/ethtool" "github.com/projectcalico/calico/felix/ip" "github.com/projectcalico/calico/felix/ipsets" "github.com/projectcalico/calico/felix/logutils" + "github.com/projectcalico/calico/felix/netlinkshim" "github.com/projectcalico/calico/felix/proto" "github.com/projectcalico/calico/felix/routetable" "github.com/projectcalico/calico/felix/rules" "github.com/projectcalico/calico/felix/vxlanfdb" - "github.com/projectcalico/calico/libcalico-go/lib/set" ) // added so that we can shim netlink for tests @@ -60,14 +55,10 @@ type netlinkHandle interface { type vxlanManager struct { // Our dependencies. - hostname string - routeTable routetable.RouteTableInterface - blackholeRouteTable routetable.RouteTableInterface - noEncapRouteTable routetable.RouteTableInterface - parentIfaceName string - lastParentDevUpdate time.Time - previouslyUsedParentNames set.Set[string] - fdb VXLANFDB + hostname string + routeTable routetable.Interface + parentIfaceName string + fdb VXLANFDB // Hold pending updates. routesByDest map[string]*proto.RouteUpdate @@ -94,14 +85,10 @@ type vxlanManager struct { nlHandle netlinkHandle dpConfig Config noEncapProtocol netlink.RouteProtocol - // Used so that we can shim the no encap route table for the tests - noEncapRTConstruct func( - interfacePrefixes []string, ipVersion uint8, netlinkTimeout time.Duration, - deviceRouteSourceAddress net.IP, deviceRouteProtocol netlink.RouteProtocol, removeExternalRoutes bool, - ) routetable.RouteTableInterface // Log context - logCtx *logrus.Entry + logCtx *logrus.Entry + opRecorder logutils.OpRecorder } type VXLANFDB interface { @@ -110,89 +97,35 @@ type VXLANFDB interface { func newVXLANManager( ipsetsDataplane dpsets.IPSetsDataplane, - rt routetable.RouteTableInterface, + mainRouteTable routetable.Interface, fdb VXLANFDB, deviceName string, dpConfig Config, opRecorder logutils.OpRecorder, ipVersion uint8, - featureDetector environment.FeatureDetectorIface, ) *vxlanManager { - nlHandle, _ := netlink.NewHandle(syscall.NETLINK_ROUTE) - - blackHoleProto := dataplanedefs.VXLANDefaultProto - if dpConfig.DeviceRouteProtocol != syscall.RTPROT_BOOT { - blackHoleProto = dpConfig.DeviceRouteProtocol - } - - var brt routetable.RouteTableInterface - if !dpConfig.RouteSyncDisabled { - logrus.Debug("RouteSyncDisabled is false.") - if ipVersion == 4 { - brt = routetable.New( - []string{routetable.InterfaceNone}, - 4, - dpConfig.NetlinkTimeout, - dpConfig.DeviceRouteSourceAddress, - blackHoleProto, - false, - unix.RT_TABLE_MAIN, - opRecorder, - featureDetector, - ) - } else if ipVersion == 6 { - brt = routetable.New( - []string{routetable.InterfaceNone}, - ipVersion, - dpConfig.NetlinkTimeout, - dpConfig.DeviceRouteSourceAddressIPv6, - blackHoleProto, - false, - unix.RT_TABLE_MAIN, - opRecorder, - featureDetector, - ) - } else { - logrus.WithField("ipVersion", ipVersion).Panic("Unknown IP version") - } - } else { - logrus.Info("RouteSyncDisabled is true, using DummyTable.") - brt = &routetable.DummyTable{} - } - + nlHandle, _ := netlinkshim.NewRealNetlink() return newVXLANManagerWithShims( ipsetsDataplane, - rt, brt, + mainRouteTable, fdb, deviceName, dpConfig, + opRecorder, nlHandle, ipVersion, - func(interfaceRegexes []string, - ipVersion uint8, - netlinkTimeout time.Duration, - deviceRouteSourceAddress net.IP, - deviceRouteProtocol netlink.RouteProtocol, - removeExternalRoutes bool, - ) routetable.RouteTableInterface { - return routetable.New(interfaceRegexes, ipVersion, netlinkTimeout, - deviceRouteSourceAddress, deviceRouteProtocol, removeExternalRoutes, unix.RT_TABLE_MAIN, - opRecorder, featureDetector, - ) - }, ) } func newVXLANManagerWithShims( ipsetsDataplane dpsets.IPSetsDataplane, - rt, brt routetable.RouteTableInterface, + mainRouteTable routetable.Interface, fdb VXLANFDB, deviceName string, dpConfig Config, + opRecorder logutils.OpRecorder, nlHandle netlinkHandle, ipVersion uint8, - noEncapRTConstruct func(interfacePrefixes []string, ipVersion uint8, netlinkTimeout time.Duration, - deviceRouteSourceAddress net.IP, deviceRouteProtocol netlink.RouteProtocol, removeExternalRoutes bool) routetable.RouteTableInterface, ) *vxlanManager { logCtx := logrus.WithField("ipVersion", ipVersion) return &vxlanManager{ @@ -202,27 +135,25 @@ func newVXLANManagerWithShims( SetID: rules.IPSetIDAllVXLANSourceNets, Type: ipsets.IPSetTypeHashNet, }, - hostname: dpConfig.Hostname, - routeTable: rt, - blackholeRouteTable: brt, - previouslyUsedParentNames: set.New[string](), - fdb: fdb, - routesByDest: map[string]*proto.RouteUpdate{}, - localIPAMBlocks: map[string]*proto.RouteUpdate{}, - vtepsByNode: map[string]*proto.VXLANTunnelEndpointUpdate{}, - myVTEPChangedC: make(chan struct{}, 1), - vxlanDevice: deviceName, - vxlanID: dpConfig.RulesConfig.VXLANVNI, - vxlanPort: dpConfig.RulesConfig.VXLANPort, - ipVersion: ipVersion, - externalNodeCIDRs: dpConfig.ExternalNodesCidrs, - routesDirty: true, - vtepsDirty: true, - dpConfig: dpConfig, - nlHandle: nlHandle, - noEncapProtocol: calculateNonEncapRouteProtocol(dpConfig), - noEncapRTConstruct: noEncapRTConstruct, - logCtx: logCtx, + hostname: dpConfig.Hostname, + routeTable: mainRouteTable, + fdb: fdb, + routesByDest: map[string]*proto.RouteUpdate{}, + localIPAMBlocks: map[string]*proto.RouteUpdate{}, + vtepsByNode: map[string]*proto.VXLANTunnelEndpointUpdate{}, + myVTEPChangedC: make(chan struct{}, 1), + vxlanDevice: deviceName, + vxlanID: dpConfig.RulesConfig.VXLANVNI, + vxlanPort: dpConfig.RulesConfig.VXLANPort, + ipVersion: ipVersion, + externalNodeCIDRs: dpConfig.ExternalNodesCidrs, + routesDirty: true, + vtepsDirty: true, + dpConfig: dpConfig, + nlHandle: nlHandle, + noEncapProtocol: calculateNonEncapRouteProtocol(dpConfig), + logCtx: logCtx, + opRecorder: opRecorder, } } @@ -397,21 +328,6 @@ func (m *vxlanManager) getLocalVTEPParent() (netlink.Link, error) { return m.getParentInterface(m.getLocalVTEP()) } -func (m *vxlanManager) GetRouteTableSyncers() []routetable.RouteTableSyncer { - rts := []routetable.RouteTableSyncer{m.routeTable, m.blackholeRouteTable} - - if time.Since(m.lastParentDevUpdate) > 5*time.Minute && m.previouslyUsedParentNames.Len() > 1 { - // Make sure the set of names doesn't grow forever. - m.previouslyUsedParentNames.Clear() - } - if m.noEncapRouteTable != nil { - m.previouslyUsedParentNames.Add(m.parentIfaceName) - rts = append(rts, m.noEncapRouteTable) - } - - return rts -} - func (m *vxlanManager) blackholeRoutes() []routetable.Target { var rtt []routetable.Target for dst := range m.localIPAMBlocks { @@ -423,8 +339,9 @@ func (m *vxlanManager) blackholeRoutes() []routetable.Target { continue } rtt = append(rtt, routetable.Target{ - Type: routetable.TargetTypeBlackhole, - CIDR: cidr, + Type: routetable.TargetTypeBlackhole, + CIDR: cidr, + Protocol: m.noEncapProtocol, }) } m.logCtx.Debug("calculated blackholes ", rtt) @@ -432,16 +349,41 @@ func (m *vxlanManager) blackholeRoutes() []routetable.Target { } func (m *vxlanManager) CompleteDeferredWork() error { + if m.parentIfaceName == "" { + // Background goroutine hasn't sent us the parent interface name yet, + // but we can look it up synchronously. OnParentNameUpdate will handle + // any duplicate update when it arrives. + parent, err := m.getLocalVTEPParent() + if err != nil { + // If we can't look up the parent interface then we're in trouble. + // It likely means that our VTEP is missing or conflicting. We + // won't be able to program same-subnet routes at all, so we'll + // fall back to programming all tunnel routes. However, unless the + // VXLAN device happens to already exist, we won't be able to + // program tunnel routes either. The RouteTable will be the + // component that spots that the interface is missing. + // + // Note: this behaviour changed when we unified all the main + // RouteTable instances into one. Before that change, we chose to + // defer creation of our "no encap" RouteTable, so that the + // dataplane would stay untouched until the conflict was resolved. + // With only a single RouteTable, we need a different fallback. + m.logCtx.WithError(err).WithField("localVTEP", m.getLocalVTEP()).Error( + "Failed to find VXLAN tunnel device parent. Missing/conflicting local VTEP? VXLAN route " + + "programming is likely to fail.") + } else { + m.parentIfaceName = parent.Attrs().Name + m.routesDirty = true + } + } + if m.vtepsDirty { m.updateNeighborsAndAllowedSources() m.vtepsDirty = false } if m.routesDirty { - err := m.updateRoutes() - if err != nil { - return err - } + m.updateRoutes() m.routesDirty = false } @@ -450,6 +392,7 @@ func (m *vxlanManager) CompleteDeferredWork() error { func (m *vxlanManager) updateNeighborsAndAllowedSources() { m.logCtx.Debug("VTEPs are dirty, updating allowed VXLAN sources and L2 neighbors.") + m.opRecorder.RecordOperation("update-vxlan-vteps") // We allow VXLAN packets from configured external sources as well as // each Calico node with a valid VTEP. @@ -483,8 +426,12 @@ func (m *vxlanManager) updateNeighborsAndAllowedSources() { m.ipsetsDataplane.AddOrReplaceIPSet(m.ipSetMetadata, allowedVXLANSources) } -func (m *vxlanManager) updateRoutes() error { - // Iterate through all of our L3 routes and send them through to the route table. +func (m *vxlanManager) updateRoutes() { + // Iterate through all of our L3 routes and send them through to the + // RouteTable. It's a little wasteful to recalculate everything but the + // RouteTable will avoid making dataplane changes for routes that haven't + // changed. + m.opRecorder.RecordOperation("update-vxlan-routes") var vxlanRoutes []routetable.Target var noEncapRoutes []routetable.Target for _, r := range m.routesByDest { @@ -509,32 +456,35 @@ func (m *vxlanManager) updateRoutes() error { } m.logCtx.WithField("vxlanRoutes", vxlanRoutes).Debug("VXLAN manager setting VXLAN tunneled routes") - m.routeTable.SetRoutes(m.vxlanDevice, vxlanRoutes) - m.blackholeRouteTable.SetRoutes(routetable.InterfaceNone, m.blackholeRoutes()) + m.routeTable.SetRoutes(routetable.RouteClassVXLANTunnel, m.vxlanDevice, vxlanRoutes) + m.routeTable.SetRoutes(routetable.RouteClassIPAMBlockDrop, routetable.InterfaceNone, m.blackholeRoutes()) - if m.noEncapRouteTable != nil { - m.logCtx.WithField("link", m.parentIfaceName).WithField("routes", noEncapRoutes).Debug( - "VXLAN manager sending unencapsulated L3 updates") - m.noEncapRouteTable.SetRoutes(m.parentIfaceName, noEncapRoutes) + if m.parentIfaceName != "" { + m.logCtx.WithFields(logrus.Fields{ + "noEncapDevice": m.parentIfaceName, + "routes": noEncapRoutes, + }).Debug("VXLAN manager sending unencapsulated L3 updates") + m.routeTable.SetRoutes(routetable.RouteClassVXLANSameSubnet, m.parentIfaceName, noEncapRoutes) } else { - return errors.New("no encap route table not set, will defer adding routes") + m.logCtx.Debug("VXLAN manager not sending unencapsulated L3 updates, no parent interface.") } - - m.logCtx.Info("VXLAN Manager completed deferred work") - return nil } func (m *vxlanManager) noEncapRoute(cidr ip.CIDR, r *proto.RouteUpdate) *routetable.Target { if !r.GetSameSubnet() { return nil } + if m.parentIfaceName == "" { + return nil + } if r.DstNodeIp == "" { return nil } noEncapRoute := routetable.Target{ - Type: routetable.TargetTypeNoEncap, - CIDR: cidr, - GW: ip.FromString(r.DstNodeIp), + Type: routetable.TargetTypeNoEncap, + CIDR: cidr, + GW: ip.FromString(r.DstNodeIp), + Protocol: m.noEncapProtocol, } return &noEncapRoute } @@ -564,34 +514,14 @@ func (m *vxlanManager) OnParentNameUpdate(name string) { m.logCtx.Warn("Empty parent interface name? Ignoring.") return } - m.logCtx.WithField("parent", name).Info("Parent interface updated, creating new routing table.") - devRouteSrcAddr := m.dpConfig.DeviceRouteSourceAddress - if m.ipVersion == 6 { - devRouteSrcAddr = m.dpConfig.DeviceRouteSourceAddressIPv6 + if name == m.parentIfaceName { + return + } + if m.parentIfaceName != "" { + // We're changing parent interface, remove the old routes. + m.routeTable.SetRoutes(routetable.RouteClassVXLANSameSubnet, m.parentIfaceName, nil) } m.parentIfaceName = name - m.lastParentDevUpdate = time.Now() - - // If we're changing the name, we need to make sure the new RouteTable will - // clean up the routes on the old interface. Add previously-used names to - // the regexp. - names := m.previouslyUsedParentNames.Slice() - if !m.previouslyUsedParentNames.Contains(m.parentIfaceName) { - names = append(names, m.parentIfaceName) - } - sort.Strings(names) - for i, name := range names { - names[i] = regexp.QuoteMeta(name) - } - - m.noEncapRouteTable = m.noEncapRTConstruct( - []string{"^" + strings.Join(names, "|") + "$"}, - m.ipVersion, - m.dpConfig.NetlinkTimeout, - devRouteSrcAddr, - m.noEncapProtocol, - false, - ) m.routesDirty = true } @@ -676,6 +606,9 @@ func (m *vxlanManager) KeepVXLANDeviceInSync( // getParentInterface returns the parent interface for the given local VTEP based on IP address. This link returned is nil // if, and only if, an error occurred func (m *vxlanManager) getParentInterface(localVTEP *proto.VXLANTunnelEndpointUpdate) (netlink.Link, error) { + if localVTEP == nil { + return nil, fmt.Errorf("local VTEP not yet known") + } m.logCtx.WithField("localVTEP", localVTEP).Debug("Getting parent interface") links, err := m.nlHandle.LinkList() if err != nil { @@ -700,11 +633,15 @@ func (m *vxlanManager) getParentInterface(localVTEP *proto.VXLANTunnelEndpointUp } } } - return nil, fmt.Errorf("Unable to find parent interface with address %s", parentDeviceIP) + return nil, fmt.Errorf("unable to find parent interface with address %s", parentDeviceIP) } // configureVXLANDevice ensures the VXLAN tunnel device is up and configured correctly. -func (m *vxlanManager) configureVXLANDevice(mtu int, localVTEP *proto.VXLANTunnelEndpointUpdate, xsumBroken bool) error { +func (m *vxlanManager) configureVXLANDevice( + mtu int, + localVTEP *proto.VXLANTunnelEndpointUpdate, + xsumBroken bool, +) error { logCtx := m.logCtx.WithFields(logrus.Fields{"device": m.vxlanDevice}) logCtx.Debug("Configuring VXLAN tunnel device") parent, err := m.getParentInterface(localVTEP) diff --git a/felix/dataplane/linux/vxlan_mgr_test.go b/felix/dataplane/linux/vxlan_mgr_test.go index 82cb73a9e60..f164c47dc8d 100644 --- a/felix/dataplane/linux/vxlan_mgr_test.go +++ b/felix/dataplane/linux/vxlan_mgr_test.go @@ -22,7 +22,9 @@ import ( log "github.com/sirupsen/logrus" dpsets "github.com/projectcalico/calico/felix/dataplane/ipsets" + "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs" "github.com/projectcalico/calico/felix/ip" + "github.com/projectcalico/calico/felix/logutils" "github.com/projectcalico/calico/felix/proto" "github.com/projectcalico/calico/felix/routetable" "github.com/projectcalico/calico/felix/rules" @@ -123,27 +125,22 @@ func (t *mockVXLANFDB) SetVTEPs(targets []vxlanfdb.VTEP) { var _ = Describe("VXLANManager", func() { var manager, managerV6 *vxlanManager - var rt, brt, prt *mockRouteTable + var rt *mockRouteTable var fdb *mockVXLANFDB BeforeEach(func() { rt = &mockRouteTable{ currentRoutes: map[string][]routetable.Target{}, } - brt = &mockRouteTable{ - currentRoutes: map[string][]routetable.Target{}, - } - prt = &mockRouteTable{ - currentRoutes: map[string][]routetable.Target{}, - } fdb = &mockVXLANFDB{} la := netlink.NewLinkAttrs() la.Name = "eth0" + opRecorder := logutils.NewSummarizer("test") manager = newVXLANManagerWithShims( dpsets.NewMockIPSets(), - rt, brt, + rt, fdb, "vxlan.calico", Config{ @@ -155,22 +152,17 @@ var _ = Describe("VXLANManager", func() { VXLANPort: 20, }, }, + opRecorder, &mockVXLANDataplane{ links: []netlink.Link{&mockLink{attrs: la}}, ipVersion: 4, }, 4, - func( - interfacePrefixes []string, ipVersion uint8, netlinkTimeout time.Duration, - deviceRouteSourceAddress net.IP, deviceRouteProtocol netlink.RouteProtocol, removeExternalRoutes bool, - ) routetable.RouteTableInterface { - return prt - }, ) managerV6 = newVXLANManagerWithShims( dpsets.NewMockIPSets(), - rt, brt, + rt, fdb, "vxlan-v6.calico", Config{ @@ -182,17 +174,12 @@ var _ = Describe("VXLANManager", func() { VXLANPort: 20, }, }, + opRecorder, &mockVXLANDataplane{ links: []netlink.Link{&mockLink{attrs: la}}, ipVersion: 6, }, 6, - func( - interfacePrefixes []string, ipVersion uint8, netlinkTimeout time.Duration, - deviceRouteSourceAddress net.IP, deviceRouteProtocol netlink.RouteProtocol, removeExternalRoutes bool, - ) routetable.RouteTableInterface { - return prt - }, ) }) @@ -219,7 +206,7 @@ var _ = Describe("VXLANManager", func() { manager.OnParentNameUpdate("eth0") Expect(manager.myVTEP).NotTo(BeNil()) - Expect(manager.noEncapRouteTable).NotTo(BeNil()) + Expect(manager.parentIfaceName).NotTo(BeEmpty()) parent, err := manager.getLocalVTEPParent() Expect(parent).NotTo(BeNil()) @@ -262,14 +249,14 @@ var _ = Describe("VXLANManager", func() { }) Expect(rt.currentRoutes["vxlan.calico"]).To(HaveLen(0)) - Expect(brt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(0)) + Expect(rt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(0)) err = manager.CompleteDeferredWork() Expect(err).NotTo(HaveOccurred()) Expect(rt.currentRoutes["vxlan.calico"]).To(HaveLen(1)) - Expect(brt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(1)) - Expect(prt.currentRoutes["eth0"]).NotTo(BeNil()) + Expect(rt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(1)) + Expect(rt.currentRoutes["eth0"]).NotTo(BeNil()) mac, err := net.ParseMAC("00:0a:95:9d:68:16") Expect(err).NotTo(HaveOccurred()) @@ -307,7 +294,7 @@ var _ = Describe("VXLANManager", func() { managerV6.OnParentNameUpdate("eth0") Expect(managerV6.myVTEP).NotTo(BeNil()) - Expect(managerV6.noEncapRouteTable).NotTo(BeNil()) + Expect(managerV6.parentIfaceName).NotTo(BeEmpty()) parent, err := managerV6.getLocalVTEPParent() Expect(parent).NotTo(BeNil()) @@ -350,14 +337,14 @@ var _ = Describe("VXLANManager", func() { }) Expect(rt.currentRoutes["vxlan-v6.calico"]).To(HaveLen(0)) - Expect(brt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(0)) + Expect(rt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(0)) err = managerV6.CompleteDeferredWork() Expect(err).NotTo(HaveOccurred()) Expect(rt.currentRoutes["vxlan-v6.calico"]).To(HaveLen(1)) - Expect(brt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(1)) - Expect(prt.currentRoutes["eth0"]).NotTo(BeNil()) + Expect(rt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(1)) + Expect(rt.currentRoutes["eth0"]).NotTo(BeNil()) mac, err := net.ParseMAC("00:0a:95:9d:68:16") Expect(err).NotTo(HaveOccurred()) @@ -372,7 +359,7 @@ var _ = Describe("VXLANManager", func() { Expect(fdb.setVTEPsCalls).To(Equal(1)) }) - It("adds the route to the default table on next try when the parent route table is not immediately found", func() { + It("should fall back to programming tunneled routes if the parent device is not known", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() parentNameC := make(chan string) @@ -395,8 +382,10 @@ var _ = Describe("VXLANManager", func() { }) err := manager.CompleteDeferredWork() - Expect(err).To(MatchError("no encap route table not set, will defer adding routes")) - Expect(manager.routesDirty).To(BeTrue()) + Expect(err).NotTo(HaveOccurred()) + Expect(manager.routesDirty).To(BeFalse()) + Expect(rt.currentRoutes["eth0"]).To(HaveLen(0)) + Expect(rt.currentRoutes[dataplanedefs.VXLANIfaceNameV4]).To(HaveLen(1)) By("Sending another local VTEP.") manager.OnUpdate(&proto.VXLANTunnelEndpointUpdate{ @@ -413,15 +402,16 @@ var _ = Describe("VXLANManager", func() { Eventually(parentNameC, "2s").Should(Receive(Equal("eth0"))) manager.OnParentNameUpdate("eth0") - Expect(prt.currentRoutes["eth0"]).To(HaveLen(0)) + Expect(rt.currentRoutes["eth0"]).To(HaveLen(0)) err = manager.CompleteDeferredWork() Expect(err).NotTo(HaveOccurred()) Expect(manager.routesDirty).To(BeFalse()) - Expect(prt.currentRoutes["eth0"]).To(HaveLen(1)) + Expect(rt.currentRoutes["eth0"]).To(HaveLen(1)) + Expect(rt.currentRoutes[dataplanedefs.VXLANIfaceNameV4]).To(HaveLen(0)) }) - It("adds the IPv6 route to the default table on next try when the parent route table is not immediately found", func() { + It("IPv6: should fall back to programming tunneled routes if the parent device is not known", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() parentNameC := make(chan string) @@ -444,8 +434,10 @@ var _ = Describe("VXLANManager", func() { }) err := managerV6.CompleteDeferredWork() - Expect(err).To(MatchError("no encap route table not set, will defer adding routes")) - Expect(managerV6.routesDirty).To(BeTrue()) + Expect(err).NotTo(HaveOccurred()) + Expect(managerV6.routesDirty).To(BeFalse()) + Expect(rt.currentRoutes["eth0"]).To(HaveLen(0)) + Expect(rt.currentRoutes[dataplanedefs.VXLANIfaceNameV6]).To(HaveLen(1)) By("Sending another local VTEP.") managerV6.OnUpdate(&proto.VXLANTunnelEndpointUpdate{ @@ -462,11 +454,12 @@ var _ = Describe("VXLANManager", func() { Eventually(parentNameC, "2s").Should(Receive(Equal("eth0"))) managerV6.OnParentNameUpdate("eth0") - Expect(prt.currentRoutes["eth0"]).To(HaveLen(0)) + Expect(rt.currentRoutes["eth0"]).To(HaveLen(0)) err = managerV6.CompleteDeferredWork() Expect(err).NotTo(HaveOccurred()) Expect(managerV6.routesDirty).To(BeFalse()) - Expect(prt.currentRoutes["eth0"]).To(HaveLen(1)) + Expect(rt.currentRoutes["eth0"]).To(HaveLen(1)) + Expect(rt.currentRoutes[dataplanedefs.VXLANIfaceNameV6]).To(HaveLen(0)) }) }) diff --git a/felix/dataplane/linux/wireguard_mgr.go b/felix/dataplane/linux/wireguard_mgr.go index 8a228fd954c..dbf77455c52 100644 --- a/felix/dataplane/linux/wireguard_mgr.go +++ b/felix/dataplane/linux/wireguard_mgr.go @@ -203,6 +203,6 @@ func (m *wireguardManager) CompleteDeferredWork() error { return nil } -func (m *wireguardManager) GetRouteTableSyncers() []routetable.RouteTableSyncer { - return []routetable.RouteTableSyncer{m.wireguardRouteTable} +func (m *wireguardManager) GetRouteTableSyncers() []routetable.SyncerInterface { + return []routetable.SyncerInterface{m.wireguardRouteTable} } diff --git a/felix/dataplane/mock/mock_dataplane.go b/felix/dataplane/mock/mock_dataplane.go index 5bc4026d8b6..4006823afe1 100644 --- a/felix/dataplane/mock/mock_dataplane.go +++ b/felix/dataplane/mock/mock_dataplane.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -165,6 +165,7 @@ func (d *MockDataplane) ActiveRoutes() set.Set[proto.RouteUpdate] { return d.activeRoutes.Copy() } + func (d *MockDataplane) EndpointToProfiles() map[string][]string { d.Lock() defer d.Unlock() @@ -183,6 +184,7 @@ func (d *MockDataplane) EndpointToPolicyOrder() map[string][]TierInfo { return copyPolOrder(d.endpointToPolicyOrder) } + func (d *MockDataplane) EndpointToUntrackedPolicyOrder() map[string][]TierInfo { d.Lock() defer d.Unlock() @@ -195,7 +197,6 @@ func (d *MockDataplane) EndpointToPreDNATPolicyOrder() map[string][]TierInfo { return copyPolOrder(d.endpointToPreDNATPolicyOrder) } - func (d *MockDataplane) ServiceAccounts() map[proto.ServiceAccountID]*proto.ServiceAccountUpdate { d.Lock() defer d.Unlock() @@ -307,6 +308,8 @@ func (d *MockDataplane) OnEvent(event interface{}) { case *proto.IPSetUpdate: newMembers := set.New[string]() for _, ip := range event.Members { + Expect(newMembers.Contains(ip)).To(BeFalse(), + "Initial IP set update contained duplicates") newMembers.Add(ip) } d.ipSets[event.Id] = newMembers diff --git a/felix/dataplane/windows/endpoint_mgr.go b/felix/dataplane/windows/endpoint_mgr.go index e2ece298b97..8a2a54daa90 100644 --- a/felix/dataplane/windows/endpoint_mgr.go +++ b/felix/dataplane/windows/endpoint_mgr.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -86,7 +86,9 @@ type hnsInterface interface { HNSListEndpointRequest() ([]hns.HNSEndpoint, error) } -func newEndpointManager(hns hnsInterface, policysets policysets.PolicySetsDataplane) *endpointManager { +func newEndpointManager(hns hnsInterface, + policysets policysets.PolicySetsDataplane, +) *endpointManager { var networkName string if os.Getenv(envNetworkName) != "" { networkName = os.Getenv(envNetworkName) @@ -191,14 +193,17 @@ func (m *endpointManager) RefreshHnsEndpointCache(forceRefresh bool) error { // Some CNI plugins do not clear endpoint properly when a pod has been torn down. // In that case, it is possible Felix sees multiple endpoints with the same IP. // We need to filter out inactive endpoints that do not attach to any container. - // An endpoint is considered to be active if its state is Attached or AttachedSharing. - // Note: Endpoint.State attribute is dependent on HNS v1 api. If hcsshim upgrades to HNS v2 - // api this will break. We then need to Reach out to Microsoft to facilate the change via HNS. - if endpoint.State.String() != "Attached" && endpoint.State.String() != "AttachedSharing" { + if len(endpoint.SharedContainers) == 0 { log.WithFields(log.Fields{ "id": endpoint.Id, "name": endpoint.Name, }).Warn("This is a stale endpoint with no container attached") + log.WithFields(log.Fields{ + "id": endpoint.Id, + "name": endpoint.Name, + "state": endpoint.State.String(), + "sharedcontainers": endpoint.SharedContainers, + }).Debug("Stale endpoint debug information") continue } ip := endpoint.IPAddress.String() + ipv4AddrSuffix @@ -324,9 +329,6 @@ func (m *endpointManager) CompleteDeferredWork() error { var missingEndpoints bool for id, workload := range m.pendingWlEpUpdates { logCxt := log.WithField("id", id) - - var inboundPolicyIds []string - var outboundPolicyIds []string var endpointId string // A non-nil workload indicates this is a pending add or update operation @@ -349,23 +351,75 @@ func (m *endpointManager) CompleteDeferredWork() error { logCxt.Info("Processing endpoint add/update") - if len(workload.Tiers) > 0 && len(workload.Tiers[0].IngressPolicies) > 0 { - logCxt.Debug("Workload Tier Policies will be applied Inbound") - inboundPolicyIds = append(inboundPolicyIds, prependAll(policysets.PolicyNamePrefix, workload.Tiers[0].IngressPolicies)...) - } else if len(workload.ProfileIds) > 0 { - logCxt.Debug("Profiles will be applied Inbound") - inboundPolicyIds = append(inboundPolicyIds, prependAll(policysets.ProfileNamePrefix, workload.ProfileIds)...) + // Figure out which tiers apply in the ingress/egress direction. We skip any tiers that have no policies + // that apply to this endpoint. At this point we're working with policy names only. + // + // Also note whether the default tier has policies or not. If the + // default tier does not have policies in a direction, then a profile should be added for that direction. + var ingressPolNames, egressPolNames [][]string + var defaultTierIngressAppliesToEP bool + var defaultTierEgressAppliesToEP bool + for _, t := range workload.Tiers { + log.Debugf("windows workload %v, tiers: %v", workload.Name, t.Name) + if len(t.IngressPolicies) > 0 { + if t.Name == "default" { + defaultTierIngressAppliesToEP = true + } + ingressPolNames = append(ingressPolNames, prependAll(policysets.PolicyNamePrefix, t.IngressPolicies)) + } + if len(t.EgressPolicies) > 0 { + if t.Name == "default" { + defaultTierEgressAppliesToEP = true + } + egressPolNames = append(egressPolNames, prependAll(policysets.PolicyNamePrefix, t.EgressPolicies)) + } + } + log.Debugf("default tier has ingress policies: %v, egress policies: %v", defaultTierIngressAppliesToEP, defaultTierEgressAppliesToEP) + + // If _no_ policies apply at all, then we fall through to the profiles. Otherwise, there's no way to get + // from policies to profiles. + if len(ingressPolNames) == 0 || !defaultTierIngressAppliesToEP { + ingressPolNames = append(ingressPolNames, prependAll(policysets.ProfileNamePrefix, workload.ProfileIds)) + } + + if len(egressPolNames) == 0 || !defaultTierEgressAppliesToEP { + egressPolNames = append(egressPolNames, prependAll(policysets.ProfileNamePrefix, workload.ProfileIds)) } - if len(workload.Tiers) > 0 && len(workload.Tiers[0].EgressPolicies) > 0 { - logCxt.Debug("Workload Tier Policies will be applied Outbound") - outboundPolicyIds = append(outboundPolicyIds, prependAll(policysets.PolicyNamePrefix, workload.Tiers[0].EgressPolicies)...) - } else if len(workload.ProfileIds) > 0 { - logCxt.Debug("Profiles will be applied Outbound") - outboundPolicyIds = append(outboundPolicyIds, prependAll(policysets.ProfileNamePrefix, workload.ProfileIds)...) + // Expand the policies into rules. + var ingressRules, egressRules [][]*hns.ACLPolicy + for _, t := range ingressPolNames { + ingressRules = append(ingressRules, m.policysetsDataplane.GetPolicySetRules(t, true)) } + for _, t := range egressPolNames { + egressRules = append(egressRules, m.policysetsDataplane.GetPolicySetRules(t, false)) + } + + // Flatten any tiers. + flatIngressRules := flattenTiers(ingressRules) + flatEgressRules := flattenTiers(egressRules) + + if log.GetLevel() >= log.DebugLevel { + for _, rule := range flatIngressRules { + log.WithFields(log.Fields{"rule": rule}).Debug("ingress rules after flattening") + } + for _, rule := range flatEgressRules { + log.WithFields(log.Fields{"rule": rule}).Debug("egress rules after flattening") + } + } + + // Make sure priorities are ascending. + rewritePriorities(flatIngressRules, policysets.PolicyRuleMaxPriority) + rewritePriorities(flatEgressRules, policysets.PolicyRuleMaxPriority) + + // Finally, add default allow rule with a host-scope to allow traffic through + // the host windows firewall. Required by l2bridge network. + // We need to add host rules after priority is rewritten because the value of the priority + // for a host rule depends on AclNoHostRulePriority feature support. + flatIngressRules = append(flatIngressRules, m.policysetsDataplane.NewHostRule(true)) + flatEgressRules = append(flatEgressRules, m.policysetsDataplane.NewHostRule(false)) - err := m.applyRules(id, endpointId, inboundPolicyIds, outboundPolicyIds) + err := m.applyRules(id, endpointId, flatIngressRules, flatEgressRules) if err != nil { // Failed to apply, this will be rescheduled and retried log.WithError(err).Error("Failed to apply rules update") @@ -432,21 +486,18 @@ func (m *endpointManager) markAllEndpointForRefresh() { // applyRules gathers all of the rules for the specified policies and sends them to hns // as an endpoint policy update (this actually applies the rules to the dataplane). -func (m *endpointManager) applyRules(workloadId proto.WorkloadEndpointID, endpointId string, inboundPolicyIds []string, outboundPolicyIds []string) error { +func (m *endpointManager) applyRules(workloadId proto.WorkloadEndpointID, endpointId string, inboundRules, outboundRules []*hns.ACLPolicy) error { logCxt := log.WithFields(log.Fields{"id": workloadId, "endpointId": endpointId}) - logCxt.WithFields(log.Fields{ - "inboundPolicyIds": inboundPolicyIds, - "outboundPolicyIds": outboundPolicyIds, - }).Info("Applying endpoint rules") + logCxt.Info("Applying endpoint rules") - var rules []*hns.ACLPolicy + rules := make([]*hns.ACLPolicy, 0, len(inboundRules)+len(outboundRules)+1) if nodeToEp := m.nodeToEndpointRule(); nodeToEp != nil { log.WithField("hostAddrs", m.hostAddrs).Debug("Adding node->endpoint allow rule") rules = append(rules, nodeToEp) } - rules = append(rules, m.policysetsDataplane.GetPolicySetRules(inboundPolicyIds, true)...) - rules = append(rules, m.policysetsDataplane.GetPolicySetRules(outboundPolicyIds, false)...) + rules = append(rules, inboundRules...) + rules = append(rules, outboundRules...) if len(rules) > 0 { if log.GetLevel() >= log.DebugLevel { diff --git a/felix/dataplane/windows/flattener.go b/felix/dataplane/windows/flattener.go new file mode 100644 index 00000000000..182ff0e5d14 --- /dev/null +++ b/felix/dataplane/windows/flattener.go @@ -0,0 +1,266 @@ +// Copyright (c) 2019 Tigera, Inc. All rights reserved. + +package windataplane + +import ( + "fmt" + "strconv" + "strings" + + "github.com/bits-and-blooms/bitset" + + "github.com/projectcalico/calico/felix/dataplane/windows/hns" + "github.com/projectcalico/calico/felix/dataplane/windows/policysets" + "github.com/projectcalico/calico/felix/iputils" + + log "github.com/sirupsen/logrus" +) + +func flattenTiers(tiers [][]*hns.ACLPolicy) []*hns.ACLPolicy { + if len(tiers) == 0 { + log.Panic("Ran out of rules") + } + + if log.GetLevel() >= log.DebugLevel { + for i, t := range tiers { + for _, rule := range t { + log.WithFields(log.Fields{"rule": rule}).Infof("flattener: tier %d", i) + } + } + } + + lastTier := tiers[len(tiers)-1] + log.Debugf("flattener: last tier is %+v", lastTier) + if log.GetLevel() >= log.DebugLevel { + for _, rule := range lastTier { + log.WithFields(log.Fields{"rule": rule}).Info("flattener: lastTier") + } + } + // For last tier, no further flattening is required. + // However, there could still be rules with `pass` action + // which should be `passed` to `default-deny`. Pre-process + // last tier before running flattenTiersRecurse. + for _, r := range lastTier { + if r.Action == policysets.ActionPass { + log.Debug("flattener: setting pass rules in last tier to block") + r.Action = hns.Block + } + } + + return flattenTiersRecurse(tiers) +} + +func flattenTiersRecurse(tiers [][]*hns.ACLPolicy) []*hns.ACLPolicy { + if len(tiers) == 0 { + log.Panic("Ran out of rules") + } + if len(tiers) == 1 { + log.Debugf("flattener: only 1 tier, returning it: %v", tiers[0]) + return tiers[0] + } + + foundPass := false + + oldFirstTier := tiers[0] + log.Debugf("flattener: old first tier: %+v", oldFirstTier) + if log.GetLevel() >= log.DebugLevel { + for _, rule := range oldFirstTier { + log.WithFields(log.Fields{"rule": rule}).Debug("flattener: old first tier") + } + } + + var newFirstTier []*hns.ACLPolicy + + log.Debugf("flattener: loop through rules of old first tier") + for _, r := range oldFirstTier { + if r.Action == policysets.ActionPass { + log.Debugf("flattener: found pass rule in old first tier: %+v", r) + foundPass = true + oldSecondTier := tiers[1] + newFirstTier = appendCombinedRules(newFirstTier, oldSecondTier, r) + } else { + newFirstTier = append(newFirstTier, r) + } + } + + if !foundPass { + // There are further tiers but no pass actions so it's impossible to get there. + log.Debug("flattener: further tiers but no pass rules found, returning old first tier") + return oldFirstTier + } + + // We've now coalesced the first and second tiers. + tiers = tiers[1:] + tiers[0] = newFirstTier + + return flattenTiersRecurse(tiers) +} + +func appendCombinedRules(newRules []*hns.ACLPolicy, secondTier []*hns.ACLPolicy, rule *hns.ACLPolicy) []*hns.ACLPolicy { + for _, r := range secondTier { + combinedRule := combineRules(rule, r) + if combinedRule == nil { + // Rule would be a no-op + continue + } + newRules = append(newRules, combinedRule) + } + + return newRules +} + +// Calculates r1 && r2 and uses the action/ID from r2. +func combineRules(r1, r2 *hns.ACLPolicy) *hns.ACLPolicy { + combined := *r2 + + if r1.Protocol != 256 { + if r2.Protocol == 256 { + combined.Protocol = r1.Protocol + } else if r1.Protocol != r2.Protocol { + return nil + } + } + var err error + combined.LocalAddresses, err = combineCIDRs(r1.LocalAddresses, r2.LocalAddresses) + if err == policysets.ErrRuleIsNoOp { + return nil + } + combined.RemoteAddresses, err = combineCIDRs(r1.RemoteAddresses, r2.RemoteAddresses) + if err == policysets.ErrRuleIsNoOp { + return nil + } + + combined.LocalPorts, err = combinePorts(r1.LocalPorts, r2.LocalPorts) + if err == policysets.ErrRuleIsNoOp { + return nil + } + combined.RemotePorts, err = combinePorts(r1.RemotePorts, r2.RemotePorts) + if err == policysets.ErrRuleIsNoOp { + return nil + } + + return &combined +} + +func combinePorts(as string, bs string) (string, error) { + if len(as) == 0 { + return bs, nil + } + if len(bs) == 0 { + return as, nil + } + + aBitset := parsePorts(as) + bBitset := parsePorts(bs) + + aBitset.InPlaceIntersection(bBitset) + if aBitset.Len() == 0 { + return "", policysets.ErrRuleIsNoOp + } + + i := uint(0) + var outPorts []string + for { + startOfRange, valid := aBitset.NextSet(i) + if !valid { + break + } + + afterEndOfRange, valid := aBitset.NextClear(startOfRange + 1) + if !valid { + panic("bitset said no end of range") + } + endOfRange := afterEndOfRange - 1 + + if startOfRange == endOfRange { + outPorts = append(outPorts, fmt.Sprint(startOfRange)) + } else { + outPorts = append(outPorts, fmt.Sprintf("%d-%d", startOfRange, endOfRange)) + } + + i = afterEndOfRange + 1 + } + + return strings.Join(outPorts, ","), nil +} + +func parsePorts(portsStr string) *bitset.BitSet { + setOfPorts := bitset.New(2 ^ 16 + 1) + for _, p := range strings.Split(portsStr, ",") { + if strings.Contains(p, "-") { + // Range + parts := strings.Split(p, "-") + low, err := strconv.Atoi(parts[0]) + if err != nil { + panic(err) + } + high, err := strconv.Atoi(parts[1]) + if err != nil { + panic(err) + } + for port := low; port <= high; port++ { + setOfPorts.Set(uint(port)) + } + } else { + // Single value + port, err := strconv.Atoi(p) + if err != nil { + panic(err) + } + setOfPorts.Set(uint(port)) + } + } + return setOfPorts +} + +func combineCIDRs(as, bs string) (string, error) { + if len(as) == 0 { + return bs, nil + } + if len(bs) == 0 { + return as, nil + } + + combined := strings.Join( + iputils.IntersectCIDRs( + strings.Split(as, ","), + strings.Split(bs, ",")), + ",", + ) + if combined == "" { + return "", policysets.ErrRuleIsNoOp + } + return combined, nil +} + +func rewritePriorities(policies []*hns.ACLPolicy, limit uint16) { + if len(policies) <= 1 { + return + } + + currentPriority := policysets.PolicyRuleBasePriority + policies[0].Priority = currentPriority + lastRule := policies[0] + + // Determine if we should always increment the rule priority. + // If the number of rules exceeds the max allowed priority (subtracting + // the base priority) then we assign the same priority to groups of + // rules that have the same direction and action. + alwaysIncrementPriority := len(policies) < int(limit-currentPriority) + + if alwaysIncrementPriority { + for i := 1; i < len(policies); i++ { + currentPriority++ + policies[i].Priority = currentPriority + } + } else { + for i := 1; i < len(policies); i++ { + if lastRule.Action != policies[i].Action { + currentPriority++ + } + + policies[i].Priority = currentPriority + lastRule = policies[i] + } + } +} diff --git a/felix/dataplane/windows/flattener_test.go b/felix/dataplane/windows/flattener_test.go new file mode 100644 index 00000000000..78cce4fe72c --- /dev/null +++ b/felix/dataplane/windows/flattener_test.go @@ -0,0 +1,226 @@ +// Copyright (c) 2019 Tigera, Inc. All rights reserved. +package windataplane + +import ( + "testing" + + . "github.com/onsi/gomega" + + "github.com/projectcalico/calico/felix/dataplane/windows/hns" + "github.com/projectcalico/calico/felix/dataplane/windows/policysets" +) + +func TestFlatten(t *testing.T) { + RegisterTestingT(t) + + t.Log("Should have no effect on a single tier with no pass rules.") + tier1 := []*hns.ACLPolicy{ + {Protocol: 256, Action: hns.Block}, + {Protocol: 256, Action: hns.Block}, + } + flatSingleTier := flattenTiers([][]*hns.ACLPolicy{tier1}) + Expect(flatSingleTier).To(Equal(tier1)) + + t.Log("Should discard unreachable tiers") + tiers := [][]*hns.ACLPolicy{ + tier1, + tier1, + } + Expect(flattenTiers(tiers)).To(Equal(tier1)) + + t.Log("Should expand a pass rule") + tierWithPass := []*hns.ACLPolicy{ + {Protocol: 256, Action: policysets.ActionPass}, + {Protocol: 100, Action: hns.Block}, + {Protocol: 100, Action: hns.Block}, + } + Expect(flattenTiers([][]*hns.ACLPolicy{ + tierWithPass, + tier1, + })).To(Equal([]*hns.ACLPolicy{ + // tier1 + {Protocol: 256, Action: hns.Block}, + {Protocol: 256, Action: hns.Block}, + // Remainder of tierWithPass + {Protocol: 100, Action: hns.Block}, + {Protocol: 100, Action: hns.Block}, + })) + + t.Log("Should combine protocol=any with a specific protocol") + Expect(flattenTiers([][]*hns.ACLPolicy{ + {{Protocol: 256, Action: policysets.ActionPass}}, + {{Protocol: 10, Action: hns.Allow}}, + })).To(Equal([]*hns.ACLPolicy{ + {Protocol: 10, Action: hns.Allow}, + })) + + t.Log("Should combine CIDRs") + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: policysets.ActionPass, LocalAddresses: "10.0.0.0/16"}, + {Action: policysets.ActionPass, LocalAddresses: "10.0.10.0/26"}, + }, + {{Action: hns.Allow, LocalAddresses: "10.0.10.0/24"}}, + })).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Allow, LocalAddresses: "10.0.10.0/24"}, + {Action: hns.Allow, LocalAddresses: "10.0.10.0/26"}, + })) + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: policysets.ActionPass, RemoteAddresses: "10.0.0.0/16,11.0.0.0/24"}, + {Action: policysets.ActionPass, RemoteAddresses: "10.0.10.0/26"}, + }, + {{Action: hns.Allow, RemoteAddresses: "10.0.10.0/24,11.0.0.0/8"}, + {Action: hns.Allow, RemoteAddresses: "12.0.0.0/8"}, + {Action: hns.Allow, LocalAddresses: "12.0.0.0/8"}, + }, + })).To(Equal([]*hns.ACLPolicy{ + // First pass rule + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24,11.0.0.0/24" /*remotes get intersected*/}, + {Action: hns.Allow, + RemoteAddresses: "10.0.0.0/16,11.0.0.0/24", /*second rule from second tier has no remotes, so inherits from pass rule*/ + LocalAddresses: "12.0.0.0/8"}, + // Second pass rule + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/26"}, + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/26", LocalAddresses: "12.0.0.0/8"}, + })) + + t.Log("Should combine Ports") + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: policysets.ActionPass, LocalPorts: "1,2,10-15"}, + {Action: policysets.ActionPass, LocalPorts: "10-15"}, + }, + {{Action: hns.Allow, LocalPorts: "2,12-16,55"}}, + })).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Allow, LocalPorts: "2,12-15"}, + {Action: hns.Allow, LocalPorts: "12-15"}, + })) + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: policysets.ActionPass, RemotePorts: "1,2,10-15"}, + {Action: policysets.ActionPass, RemotePorts: "10-15"}, + }, + {{Action: hns.Allow, RemotePorts: "2,12-16,55"}}, + })).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Allow, RemotePorts: "2,12-15"}, + {Action: hns.Allow, RemotePorts: "12-15"}, + })) + + t.Log("Should recurse with non-overlapping pass on second tier") + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: policysets.ActionPass, RemoteAddresses: "10.0.0.0/16,11.0.0.0/24"}, + {Action: policysets.ActionPass, RemoteAddresses: "10.0.10.0/26"}, + }, + {{Action: hns.Allow, RemoteAddresses: "10.0.10.0/24,11.0.0.0/8"}, + {Action: policysets.ActionPass, RemoteAddresses: "12.0.0.0/8"}, + {Action: hns.Allow, LocalAddresses: "12.0.0.0/8"}, + }, + { + {Action: hns.Allow, RemoteAddresses: "10.0.11.0/28"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.0/28"}, + }, + })).To(Equal([]*hns.ACLPolicy{ + // First pass rule + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24,11.0.0.0/24"}, + {Action: hns.Allow, RemoteAddresses: "10.0.0.0/16,11.0.0.0/24", LocalAddresses: "12.0.0.0/8"}, + // Second pass rule + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/26"}, + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/26", LocalAddresses: "12.0.0.0/8"}, + })) + + t.Log("Should recurse with overlapping pass on second tier") + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: policysets.ActionPass, RemoteAddresses: "10.0.0.0/16,11.0.0.0/24"}, + {Action: policysets.ActionPass, RemoteAddresses: "10.0.10.0/26"}, + }, + {{Action: hns.Allow, RemoteAddresses: "10.0.10.0/24,11.0.0.0/8"}, + {Action: policysets.ActionPass, RemoteAddresses: "10.0.10.0/24"}, + {Action: hns.Allow, LocalAddresses: "12.0.0.0/8"}, + }, + { + {Action: hns.Allow, RemoteAddresses: "10.0.11.0/28"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.0/28"}, + }, + })).To(Equal([]*hns.ACLPolicy{ + // First pass rule + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24,11.0.0.0/24"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.0/28"}, + {Action: hns.Allow, RemoteAddresses: "10.0.0.0/16,11.0.0.0/24", LocalAddresses: "12.0.0.0/8"}, + // Second pass rule + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/26"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.0/28"}, + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/26", LocalAddresses: "12.0.0.0/8"}, + })) + + t.Log("Should block with pass in last tier") + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24", LocalPorts: "6000"}, + {Action: policysets.ActionPass, RemoteAddresses: "10.0.10.0/24"}, + }, + { + {Action: hns.Block, RemoteAddresses: "10.0.10.1/32", LocalPorts: "6379"}, + {Action: policysets.ActionPass, RemoteAddresses: "10.0.10.2/32", LocalPorts: "6380, 6381"}, + {Action: hns.Block, RemoteAddresses: "10.0.0.0/8", LocalPorts: "6390-6400"}, + }, + })).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24", LocalPorts: "6000"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.1/32", LocalPorts: "6379"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.2/32", LocalPorts: "6380, 6381"}, + {Action: hns.Block, RemoteAddresses: "10.0.10.0/24", LocalPorts: "6390-6400"}, + })) + + t.Log("Should pass to last tier which has only the rule from the profile") + Expect(flattenTiers([][]*hns.ACLPolicy{ + { + {Action: hns.Block, RemoteAddresses: "192.168.1.123/32", LocalPorts: "8080"}, + {Action: policysets.ActionPass}, + }, + { + // This would be the allow rule added for the profile. + {Action: hns.Allow, Protocol: 256}, + }, + })).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Block, RemoteAddresses: "192.168.1.123/32", LocalPorts: "8080"}, + {Action: hns.Allow}, + })) +} + +func TestReWritePriority(t *testing.T) { + RegisterTestingT(t) + + t.Log("Should write incrementing priority") + policies := []*hns.ACLPolicy{ + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24", Priority: 1000}, + {Action: hns.Allow, RemoteAddresses: "10.0.11.0/24", Priority: 1001}, + {Action: hns.Block, RemoteAddresses: "10.0.12.0/24", Priority: 1002}, + {Action: hns.Block, RemoteAddresses: "10.0.13.0/24", Priority: 1003}, + } + + rewritePriorities(policies, policysets.PolicyRuleMaxPriority) + Expect(policies).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24", Priority: 1000}, + {Action: hns.Allow, RemoteAddresses: "10.0.11.0/24", Priority: 1001}, + {Action: hns.Block, RemoteAddresses: "10.0.12.0/24", Priority: 1002}, + {Action: hns.Block, RemoteAddresses: "10.0.13.0/24", Priority: 1003}, + })) + + t.Log("Should write aggregated priority") + policies = []*hns.ACLPolicy{ + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24", Priority: 1000}, + {Action: hns.Allow, RemoteAddresses: "10.0.11.0/24", Priority: 1001}, + {Action: hns.Block, RemoteAddresses: "10.0.12.0/24", Priority: 1002}, + {Action: hns.Block, RemoteAddresses: "10.0.13.0/24", Priority: 1003}, + } + + rewritePriorities(policies, 1004) + Expect(policies).To(Equal([]*hns.ACLPolicy{ + {Action: hns.Allow, RemoteAddresses: "10.0.10.0/24", Priority: 1000}, + {Action: hns.Allow, RemoteAddresses: "10.0.11.0/24", Priority: 1000}, + {Action: hns.Block, RemoteAddresses: "10.0.12.0/24", Priority: 1001}, + {Action: hns.Block, RemoteAddresses: "10.0.13.0/24", Priority: 1001}, + })) +} diff --git a/felix/dataplane/windows/policy_mgr_test.go b/felix/dataplane/windows/policy_mgr_test.go index 69f0630045d..481dcb67b0e 100644 --- a/felix/dataplane/windows/policy_mgr_test.go +++ b/felix/dataplane/windows/policy_mgr_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -55,8 +55,6 @@ func TestPolicyManager(t *testing.T) { {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1000}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host, Priority: 100}, }), "unexpected rules returned for ingress rules update for policy-pol1") //assertion for egress rules @@ -65,8 +63,6 @@ func TestPolicyManager(t *testing.T) { {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Switch, Priority: 1000}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host, Priority: 100}, }), "unexpected rules returned for egress rules update for policy-pol1") //remove policy here @@ -77,8 +73,6 @@ func TestPolicyManager(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"policy-pol1"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host, Priority: 100}, }), "unexpected rules returned after ActivePolicyRemove event for policy-pol1") //Apply profile update @@ -100,8 +94,6 @@ func TestPolicyManager(t *testing.T) { {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1000}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host, Priority: 100}, }), "unexpected rules returned for ingress rules update for profile-prof1") //assertion for egress rules @@ -110,8 +102,6 @@ func TestPolicyManager(t *testing.T) { {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Switch, Priority: 1000}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host, Priority: 100}, }), "unexpected rules returned for egress rules update for profile-prof1") //remove profile update @@ -122,8 +112,6 @@ func TestPolicyManager(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"profile-prof1"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host, Priority: 100}, }), "unexpected rules returned after ActiveProfileRemove event for profile-prof1") } diff --git a/felix/dataplane/windows/policysets/policyset_defs.go b/felix/dataplane/windows/policysets/policyset_defs.go index 5b0456c54e7..f22f9fdd407 100644 --- a/felix/dataplane/windows/policysets/policyset_defs.go +++ b/felix/dataplane/windows/policysets/policyset_defs.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,10 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/set" ) +const ( + ActionPass hns.ActionType = "pass" +) + const ( // the ip family of this policy set, currently set to V4. // V6 will be added once dataplane support is available. @@ -29,6 +33,8 @@ const ( HostToEndpointRulePriority uint16 = 900 // Start of range of priorities used for policy set rules. PolicyRuleBasePriority uint16 = 1000 + // Max policy priority value. + PolicyRuleMaxPriority uint16 = 65000 // prefix to use for all policy names PolicyNamePrefix string = "policy-" // prefix to use for all profile names @@ -66,6 +72,7 @@ type PolicySetsDataplane interface { NewRule(isInbound bool, priority uint16) *hns.ACLPolicy GetPolicySetRules(setIds []string, isInbound bool) (rules []*hns.ACLPolicy) ProcessIpSetUpdate(ipSetId string) []string + NewHostRule(bool) *hns.ACLPolicy } // policySet holds the state for a particular Policy set. diff --git a/felix/dataplane/windows/policysets/policysets.go b/felix/dataplane/windows/policysets/policysets.go index ed19f5c7576..0aa14a03a4a 100644 --- a/felix/dataplane/windows/policysets/policysets.go +++ b/felix/dataplane/windows/policysets/policysets.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -175,10 +175,6 @@ func (s *PolicySets) GetPolicySetRules(setIds []string, isInbound bool) (rules [ currentPriority++ rules = append(rules, s.NewRule(isInbound, currentPriority)) - // Finally, for RS3 only, add default allow rule with a host-scope to allow traffic through - // the host windows firewall - rules = append(rules, s.NewHostRule(isInbound)) - return } @@ -352,7 +348,9 @@ func (s *PolicySets) protoRuleToHnsRules(policyId string, pRule *proto.Rule, isI aclPolicy.Action = hns.Allow case "deny": aclPolicy.Action = hns.Block - case "next-tier", "pass", "log": + case "next-tier", "pass": + aclPolicy.Action = ActionPass + case "log": logCxt.WithField("action", ruleCopy.Action).Info("This rule action is not supported, rule will be skipped") return nil, ErrNotSupported default: diff --git a/felix/dataplane/windows/policysets/policysets_test.go b/felix/dataplane/windows/policysets/policysets_test.go index d587990a1e7..3401b4282da 100644 --- a/felix/dataplane/windows/policysets/policysets_test.go +++ b/felix/dataplane/windows/policysets/policysets_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -49,8 +49,6 @@ func TestRuleRenderingWithStaticRules(t *testing.T) { RuleType: hns.Host, Priority: 300, RemoteAddresses: "10.0.0.2/32", RemotePorts: "90"}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for unknown policy") // Empty policy should return no rules (apart from the default drop). @@ -65,8 +63,6 @@ func TestRuleRenderingWithStaticRules(t *testing.T) { RuleType: hns.Host, Priority: 300, RemoteAddresses: "10.0.0.2/32", RemotePorts: "90"}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for empty policy") Expect(ps.GetPolicySetRules([]string{"empty"}, false)).To(Equal([]*hns.ACLPolicy{ @@ -75,8 +71,6 @@ func TestRuleRenderingWithStaticRules(t *testing.T) { RuleType: hns.Switch, Priority: 200, RemoteAddresses: "10.0.0.1/32", RemotePorts: "80"}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host}, }), "unexpected rules returned for empty policy") // Tests of basic policy matches: CIDRs, protocol, ports. @@ -150,8 +144,6 @@ func TestRuleRenderingWithStaticRules(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1002}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for basic policy") Expect(ps.GetPolicySetRules([]string{"basic"}, false)).To(Equal([]*hns.ACLPolicy{ @@ -166,8 +158,6 @@ func TestRuleRenderingWithStaticRules(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host}, }), "unexpected rules returned for basic policy") } @@ -192,8 +182,6 @@ func TestRuleRendering(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"unknown"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for unknown policy") // Empty policy should return no rules (apart from the default drop). @@ -205,8 +193,6 @@ func TestRuleRendering(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"empty"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for empty policy") // Tests of basic policy matches: CIDRs, protocol, ports. @@ -271,8 +257,6 @@ func TestRuleRendering(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1002}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for basic policy") // Tests for Profile @@ -285,8 +269,6 @@ func TestRuleRendering(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"empty-profile"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for empty profile") // Test for Rule with profile @@ -307,8 +289,6 @@ func TestRuleRendering(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for profile") //Test with Mixed CIDR to filterout IpV4 @@ -346,8 +326,6 @@ func TestRuleRendering(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"mixed-cidr"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for mixed-cidr") //Outbound policy with SrcNet @@ -370,8 +348,6 @@ func TestRuleRendering(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host}, }), "unexpected rules returned for outbound policy with SrcNet") } @@ -426,8 +402,6 @@ func TestIpPortRuleRendering(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host}, }), "unexpected rules returned for IP+port policy") } @@ -481,8 +455,6 @@ func TestIpPortRuleRenderingMultiPort(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host}, }), "unexpected rules returned for IP+port policy") } @@ -518,8 +490,6 @@ func TestIpPortRuleRenderingEmptyIPSet(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"basic"}, false)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.Out, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.Out, RuleType: hns.Host}, }), "unexpected rules returned for IP+port policy") } @@ -562,8 +532,6 @@ func TestNegativeTestCases(t *testing.T) { // Only the Default rules should exist. // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for ipset-that-does-not-exist") //Negative test: Unsupported protocol @@ -587,8 +555,6 @@ func TestNegativeTestCases(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rule returned for Unsupported protocol") //Negative test: Unsupported IP version (IP v6) @@ -608,8 +574,6 @@ func TestNegativeTestCases(t *testing.T) { //The rule with IP v6 should be skipped // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rule returned for unsupported IP version") //Negative test: Named port @@ -629,8 +593,6 @@ func TestNegativeTestCases(t *testing.T) { //The rule with named port should be skipped // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rule with named port") //Negative test: ICMP type @@ -649,8 +611,6 @@ func TestNegativeTestCases(t *testing.T) { //The rule with ICMP type should be skipped // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rule with ICMP Type") //Negative test: With Negative Matches @@ -669,8 +629,6 @@ func TestNegativeTestCases(t *testing.T) { //The rule with negative match should be skipped // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rule with Negative match") //Test with invalid argument to AddOrReplacePolicySet (Other than Profile/Policy) @@ -681,8 +639,6 @@ func TestNegativeTestCases(t *testing.T) { Expect(ps.GetPolicySetRules([]string{"invalid-arg"}, true)).To(Equal([]*hns.ACLPolicy{ // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned when invalid argument is passed to addOrReplacePolicySet function") //Negative test for protoRuleToHnsRules @@ -1024,8 +980,6 @@ func TestMultiIpPortChunks(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for selector multi ips policy") // Source and dest IP sets should be converted into hns rule with multi ips. @@ -1049,8 +1003,6 @@ func TestMultiIpPortChunks(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for selector ipset multi ips") // The source IP set should be intersected with the source CIDR. @@ -1105,8 +1057,6 @@ func TestMultiIpPortChunks(t *testing.T) { // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for selector CIDR filtering policy") //Complete coverage of IPSetUpdate @@ -1131,8 +1081,6 @@ func TestMultiIpPortChunks(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned after ipset update") // Test for the ProcessIpSetUpdate while applying policy after updating the ipset @@ -1152,8 +1100,6 @@ func TestMultiIpPortChunks(t *testing.T) { // Only the Default rules should exist. // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for ipset-update") //Updating the ipset @@ -1194,8 +1140,6 @@ func TestMultiIpPortChunks(t *testing.T) { }, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for ipset-update") //Test where ProcessIpSetUpdate() receives an ipset-Id that doesn't have any policies linked @@ -1225,8 +1169,6 @@ func TestMultiIpPortChunks(t *testing.T) { // We expect the rules to be skipped as no overlapping exist // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "unexpected rules returned for no-overlapping") } @@ -1260,8 +1202,6 @@ func TestPolicyOrdering(t *testing.T) { Id: "deny--0"}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1002}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "incorrect rules returned for allow,deny") Expect(ps.GetPolicySetRules([]string{"allow", "allow"}, true)).To(Equal([]*hns.ACLPolicy{ @@ -1271,8 +1211,6 @@ func TestPolicyOrdering(t *testing.T) { Id: "allow--0"}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1001}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "incorrect rules returned for allow,allow") Expect(ps.GetPolicySetRules([]string{"deny", "allow"}, true)).To(Equal([]*hns.ACLPolicy{ @@ -1282,8 +1220,6 @@ func TestPolicyOrdering(t *testing.T) { Id: "allow--0"}, // Default deny rule. {Type: hns.ACL, Protocol: 256, Action: hns.Block, Direction: hns.In, RuleType: hns.Switch, Priority: 1002}, - // Default host/pod rule. - {Type: hns.ACL, Protocol: 256, Action: hns.Allow, Direction: hns.In, RuleType: hns.Host}, }), "incorrect rules returned for deny,allow") } diff --git a/felix/docker-image/calico-felix-wrapper b/felix/docker-image/calico-felix-wrapper index b4ba0fc5aad..add2faca77d 100755 --- a/felix/docker-image/calico-felix-wrapper +++ b/felix/docker-image/calico-felix-wrapper @@ -45,7 +45,8 @@ while true; do source /extra-env.sh echo "calico-felix-wrapper: Starting calico-felix" - calico-felix & + # Only enable tracebacks for Felix, not other binaries. + GOTRACEBACK=${FELIX_GOTRACEBACK} calico-felix & pid=$! echo "calico-felix-wrapper: Started calico-felix, PID=$pid" wait $pid diff --git a/felix/environment/feature_detect_linux.go b/felix/environment/feature_detect_linux.go index 3aa6328bde4..a2e2dfbb9d3 100644 --- a/felix/environment/feature_detect_linux.go +++ b/felix/environment/feature_detect_linux.go @@ -50,6 +50,8 @@ var ( v3Dot10Dot0 = MustParseVersion("3.10.0") // v3Dot14Dot0 added the random-fully feature on the iptables interface. v3Dot14Dot0 = MustParseVersion("3.14.0") + // v5Dot7Dot0 contains a fix for checksum offloading. + v5Dot7Dot0 = MustParseVersion("5.7.0") // v5Dot14Dot0 is the fist kernel version that IPIP tunnels acts like other L3 // devices where bpf programs only see inner IP header. In RHEL based distros, // kernel 4.18.0 (v4Dot18Dot0_330) is the first one with this behavior. @@ -130,7 +132,7 @@ func (d *FeatureDetector) refreshFeaturesLockHeld() { SNATFullyRandom: iptV.Compare(v1Dot6Dot0) >= 0 && kerV.Compare(v3Dot14Dot0) >= 0, MASQFullyRandom: iptV.Compare(v1Dot6Dot2) >= 0 && kerV.Compare(v3Dot14Dot0) >= 0, RestoreSupportsLock: iptV.Compare(v1Dot6Dot2) >= 0, - ChecksumOffloadBroken: true, // Was supposed to be fixed in v5.7 but still seems to be broken. + ChecksumOffloadBroken: kerV.Compare(v5Dot7Dot0) <= 0, IPIPDeviceIsL3: d.ipipDeviceIsL3(), KernelSideRouteFiltering: netlinkSupportsStrict, } diff --git a/felix/environment/feature_detect_test.go b/felix/environment/feature_detect_test.go index dbdc096cbcc..9fe2d8cc583 100644 --- a/felix/environment/feature_detect_test.go +++ b/felix/environment/feature_detect_test.go @@ -147,6 +147,16 @@ func TestFeatureDetection(t *testing.T) { ChecksumOffloadBroken: true, }, }, + { + "iptables v1.8.4", + "Linux version 5.8.0", + Features{ + RestoreSupportsLock: true, + SNATFullyRandom: true, + MASQFullyRandom: true, + ChecksumOffloadBroken: false, + }, + }, } { tst := tst t.Run("iptables version "+tst.iptablesVersion+" kernel "+tst.kernelVersion, func(t *testing.T) { @@ -507,32 +517,28 @@ func TestBPFFeatureDetection(t *testing.T) { { "Linux version 5.10.0 - ubuntu", Features{ - IPIPDeviceIsL3: false, - ChecksumOffloadBroken: true, + IPIPDeviceIsL3: false, }, map[string]string{}, }, { "Linux version 5.14.0 - something else", Features{ - IPIPDeviceIsL3: true, - ChecksumOffloadBroken: true, + IPIPDeviceIsL3: true, }, map[string]string{}, }, { "Linux version 5.15.0", Features{ - IPIPDeviceIsL3: true, - ChecksumOffloadBroken: true, + IPIPDeviceIsL3: true, }, map[string]string{}, }, { "Linux version 5.10.0 - Default", Features{ - IPIPDeviceIsL3: true, - ChecksumOffloadBroken: true, + IPIPDeviceIsL3: true, }, map[string]string{ "IPIPDeviceIsL3": "true", @@ -541,8 +547,7 @@ func TestBPFFeatureDetection(t *testing.T) { { "Linux version 5.14.0", Features{ - IPIPDeviceIsL3: false, - ChecksumOffloadBroken: true, + IPIPDeviceIsL3: false, }, map[string]string{ "IPIPDeviceIsL3": "false", @@ -551,8 +556,7 @@ func TestBPFFeatureDetection(t *testing.T) { { "Linux version 5.16.0 - Ubuntu", Features{ - IPIPDeviceIsL3: false, - ChecksumOffloadBroken: true, + IPIPDeviceIsL3: false, }, map[string]string{ "IPIPDeviceIsL3": "false", diff --git a/felix/fv/bpf_attach_test.go b/felix/fv/bpf_attach_test.go index aef904efad0..38fe5ff6005 100644 --- a/felix/fv/bpf_attach_test.go +++ b/felix/fv/bpf_attach_test.go @@ -124,7 +124,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf reattach object", tc.Felixes[0].Exec("ifconfig", "eth20", "up") Eventually(getBPFNet, "15s", "1s").Should(ContainElements("eth10", "eth20")) - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgHEP, map[string]uint32{"eth10": ifstate.FlgIPv4Ready | ifstate.FlgHEP, "eth20": ifstate.FlgIPv4Ready | ifstate.FlgHEP}) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, ifstate.FlgHEP, map[string]uint32{"eth10": ifstate.FlgIPv4Ready | ifstate.FlgHEP, "eth20": ifstate.FlgIPv4Ready | ifstate.FlgHEP}) By("Creating a bond interface and eth10, eth20 to the bond") tc.Felixes[0].Exec("ip", "link", "add", "bond0", "type", "bond", "mode", "802.3ad") @@ -136,20 +136,20 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf reattach object", time.Sleep(0 * time.Second) Eventually(getBPFNet, "15s", "1s").Should(ContainElement("bond0")) Eventually(getBPFNet, "15s", "1s").ShouldNot(ContainElements("eth10", "eth20")) - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgHEP, map[string]uint32{"bond0": ifstate.FlgIPv4Ready | ifstate.FlgBond}) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, ifstate.FlgHEP, map[string]uint32{"bond0": ifstate.FlgIPv4Ready | ifstate.FlgBond}) By("Removing eth10 from bond") tc.Felixes[0].Exec("ip", "link", "set", "eth10", "nomaster") tc.Felixes[0].Exec("ifconfig", "eth10", "up") Eventually(getBPFNet, "15s", "1s").ShouldNot(ContainElement("eth20")) Eventually(getBPFNet, "15s", "1s").Should(ContainElements("bond0", "eth10")) - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgHEP, map[string]uint32{"bond0": ifstate.FlgIPv4Ready | ifstate.FlgBond, "eth10": ifstate.FlgIPv4Ready | ifstate.FlgHEP}) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, ifstate.FlgHEP, map[string]uint32{"bond0": ifstate.FlgIPv4Ready | ifstate.FlgBond, "eth10": ifstate.FlgIPv4Ready | ifstate.FlgHEP}) By("Removing eth20 from bond") tc.Felixes[0].Exec("ip", "link", "set", "eth20", "nomaster") tc.Felixes[0].Exec("ifconfig", "eth20", "up") Eventually(getBPFNet, "15s", "1s").Should(ContainElements("bond0", "eth10", "eth20")) - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgHEP, map[string]uint32{"eth10": ifstate.FlgIPv4Ready | ifstate.FlgHEP, "eth20": ifstate.FlgIPv4Ready | ifstate.FlgHEP}) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, ifstate.FlgHEP, map[string]uint32{"eth10": ifstate.FlgIPv4Ready | ifstate.FlgHEP, "eth20": ifstate.FlgIPv4Ready | ifstate.FlgHEP}) By("Creating a bond interface which does match BPFDataIfacePattern") tc.Felixes[0].Exec("ip", "link", "add", "foo0", "type", "bond", "mode", "802.3ad") diff --git a/felix/fv/bpf_dual_stack_test.go b/felix/fv/bpf_dual_stack_test.go index cb7bc3031e9..df06d42969c 100644 --- a/felix/fv/bpf_dual_stack_test.go +++ b/felix/fv/bpf_dual_stack_test.go @@ -22,6 +22,7 @@ import ( "net" "regexp" "strconv" + "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -272,8 +273,8 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { if !ipv6Dataplane { JustBeforeEach(func() { tc.TriggerDelayedStart() - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, nil) - ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready, nil) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, ifstate.FlgHEP, nil) + ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready, ifstate.FlgHEP, nil) }) It("should drop ipv6 packets at workload interface and allow ipv6 packets at host interface when in IPv4 only mode", func() { // IPv4 connectivity must work. @@ -364,8 +365,8 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { tc.TriggerDelayedStart() - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, nil) - ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, nil) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready, ifstate.FlgHEP, nil) + ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgHEP, nil) cc.ExpectSome(w[0][1], w[0][0]) cc.ExpectSome(w[1][0], w[0][0]) cc.ExpectSome(w[1][1], w[0][0]) @@ -397,7 +398,7 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { _, err = k8sClient.CoreV1().Nodes().UpdateStatus(context.Background(), node, metav1.UpdateOptions{}) Expect(err).NotTo(HaveOccurred()) - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, nil) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgHEP, nil) cc.ExpectSome(w[0][1], w[0][0]) cc.ExpectSome(w[1][0], w[0][0]) cc.ExpectSome(w[1][1], w[0][0]) @@ -412,8 +413,8 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { tc.TriggerDelayedStart() externalClient := infrastructure.RunExtClient("ext-client") _ = externalClient - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, nil) - ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, nil) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgHEP, nil) + ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgHEP, nil) tcpdump := externalClient.AttachTCPDump("any") tcpdump.SetLogEnabled(true) @@ -430,6 +431,25 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { Should(BeNumerically(">", 0), matcher) externalClient.Stop() }) + + It("should have both IPv4 and IPv6 routes for a dual stack UDP service", func() { + tc.TriggerDelayedStart() + ensureAllNodesBPFProgramsAttached(tc.Felixes) + k8sClient = infra.(*infrastructure.K8sDatastoreInfra).K8sClient + _ = k8sClient + testSvc = k8sServiceForDualStack("test-svc", clusterIPs, w[0][0], 80, 8055, int32(npPort), "udp") + testSvcNamespace = testSvc.ObjectMeta.Namespace + _, err := k8sClient.CoreV1().Services(testSvcNamespace).Create(context.Background(), testSvc, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + Eventually(k8sGetEpsForServiceFunc(k8sClient, testSvc), "10s").Should(HaveLen(1), + "Service endpoints didn't get created? Is controller-manager happy?") + Eventually(func() bool { + return checkServiceRoute(tc.Felixes[0], testSvc.Spec.ClusterIPs[0]) + }, 10*time.Second, 300*time.Millisecond).Should(BeTrue(), "Failed to sync with udp service") + Eventually(func() bool { + return checkServiceRoute(tc.Felixes[0], testSvc.Spec.ClusterIPs[1]) + }, 10*time.Second, 300*time.Millisecond).Should(BeTrue(), "Failed to sync with udp service") + }) } Context("with IPv6 addresses only", func() { @@ -446,13 +466,12 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { ensureBPFProgramsAttachedOffsetWithIPVersion(1, f, false, true, "eth0") } - felixReady := func(f *infrastructure.Felix) int { - return healthStatus("["+f.IPv6+"]", "9099", "readiness") - } - for _, f := range tc.Felixes { - Eventually(felixReady(f), "10s", "330ms").Should(BeGood()) - Consistently(felixReady(f), "10s", "1s").Should(BeGood()) + felixReady := func() int { + return healthStatus("["+f.IPv6+"]", "9099", "readiness") + } + Eventually(felixReady, "10s", "330ms").Should(BeGood()) + Consistently(felixReady, "10s", "1s").Should(BeGood()) } cc.Expect(None, w[0][1], w[0][0]) @@ -482,13 +501,12 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool { ensureBPFProgramsAttachedOffsetWithIPVersion(1, f, true, false, "eth0") } - felixReady := func(f *infrastructure.Felix) int { - return healthStatus(f.IP, "9099", "readiness") - } - for _, f := range tc.Felixes { - Eventually(felixReady(f), "10s", "330ms").Should(BeGood()) - Consistently(felixReady(f), "10s", "1s").Should(BeGood()) + felixReady := func() int { + return healthStatus(f.IP, "9099", "readiness") + } + Eventually(felixReady, "10s", "330ms").Should(BeGood()) + Consistently(felixReady, "10s", "1s").Should(BeGood()) } cc.Expect(None, w[0][1], w[0][0], ExpectWithIPVersion(6)) @@ -539,9 +557,9 @@ func removeIPv6Address(k8sClient *kubernetes.Clientset, felix *infrastructure.Fe felix.Exec("ip", "-6", "addr", "del", felix.Container.IPv6+"/64", "dev", "eth0") } -func ensureRightIFStateFlags(felix *infrastructure.Felix, ready uint32, additionalInterfaces map[string]uint32) { +func ensureRightIFStateFlags(felix *infrastructure.Felix, ready uint32, hostIfType uint32, additionalInterfaces map[string]uint32) { expectedIfacesToFlags := map[string]uint32{ - "eth0": ifstate.FlgHEP | ready, + "eth0": hostIfType | ready, } if additionalInterfaces != nil { diff --git a/felix/fv/bpf_map_resize_test.go b/felix/fv/bpf_map_resize_test.go index 8f6f43ac82f..7faf747a0ab 100644 --- a/felix/fv/bpf_map_resize_test.go +++ b/felix/fv/bpf_map_resize_test.go @@ -17,17 +17,15 @@ package fv_test import ( - "context" "encoding/base64" "encoding/json" + "fmt" "net" - "os" "strings" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/calico/felix/bpf/conntrack" @@ -35,17 +33,17 @@ import ( "github.com/projectcalico/calico/felix/bpf/maps" "github.com/projectcalico/calico/felix/bpf/nat" "github.com/projectcalico/calico/felix/bpf/routes" + "github.com/projectcalico/calico/felix/fv/connectivity" "github.com/projectcalico/calico/felix/fv/infrastructure" + "github.com/projectcalico/calico/felix/fv/workload" "github.com/projectcalico/calico/felix/timeshim" "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" - "github.com/projectcalico/calico/libcalico-go/lib/errors" - "github.com/projectcalico/calico/libcalico-go/lib/options" ) var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test configurable map size", []apiconfig.DatastoreType{apiconfig.EtcdV3}, func(getInfra infrastructure.InfraFactory) { - if os.Getenv("FELIX_FV_ENABLE_BPF") != "true" { + if !BPFMode() { // Non-BPF run. return } @@ -54,41 +52,30 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test configurable infra infrastructure.DatastoreInfra tc infrastructure.TopologyContainers client client.Interface + + w [2]*workload.Workload + cc *connectivity.Checker ) BeforeEach(func() { infra = getInfra() opts := infrastructure.DefaultTopologyOptions() tc, client = infrastructure.StartNNodeTopology(1, opts, infra) + + infra.AddDefaultAllow() }) AfterEach(func() { if CurrentGinkgoTestDescription().Failed { infra.DumpErrorData() } - + for _, wl := range w { + wl.Stop() + } tc.Stop() infra.Stop() }) - updateFelixConfig := func(deltaFn func(*api.FelixConfiguration)) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - cfg, err := client.FelixConfigurations().Get(ctx, "default", options.GetOptions{}) - if _, doesNotExist := err.(errors.ErrorResourceDoesNotExist); doesNotExist { - cfg = api.NewFelixConfiguration() - cfg.Name = "default" - deltaFn(cfg) - _, err = client.FelixConfigurations().Create(ctx, cfg, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) - } else { - Expect(err).NotTo(HaveOccurred()) - deltaFn(cfg) - _, err = client.FelixConfigurations().Update(ctx, cfg, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) - } - } - It("should copy data from old map to new map", func() { srcIP := net.IPv4(123, 123, 123, 123) dstIP := net.IPv4(121, 121, 121, 121) @@ -106,7 +93,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test configurable Expect(err).NotTo(HaveOccurred()) Expect(strings.Count(out, srcIP.String())).To(Equal(1), "entry not found in conntrack map") newCtMapSize := 6000 - updateFelixConfig(func(cfg *api.FelixConfiguration) { + infrastructure.UpdateFelixConfiguration(client, func(cfg *api.FelixConfiguration) { cfg.Spec.BPFMapSizeConntrack = &newCtMapSize }) @@ -115,7 +102,6 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test configurable out, err = tc.Felixes[0].ExecOutput("calico-bpf", "conntrack", "dump") Expect(err).NotTo(HaveOccurred()) Expect(strings.Count(out, srcIP.String())).To(Equal(1), "entry not found in conntrack map") - }) It("should program new map sizes", func() { @@ -141,7 +127,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test configurable newNATAffSize := 4000 newIpSetMapSize := 5000 newCtMapSize := 6000 - updateFelixConfig(func(cfg *api.FelixConfiguration) { + infrastructure.UpdateFelixConfiguration(client, func(cfg *api.FelixConfiguration) { cfg.Spec.BPFMapSizeRoute = &newRtSize cfg.Spec.BPFMapSizeNATFrontend = &newNATFeSize cfg.Spec.BPFMapSizeNATBackend = &newNATBeSize @@ -155,6 +141,24 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test configurable Eventually(getMapSizeFn(felix, affMap), "10s", "200ms").Should(Equal(newNATAffSize)) Eventually(getMapSizeFn(felix, ipsMap), "10s", "200ms").Should(Equal(newIpSetMapSize)) Eventually(getMapSizeFn(felix, ctMap), "10s", "200ms").Should(Equal(newCtMapSize)) + + // Add some workloads after resize to verify that provisioning is working with the new map sizes. + for i := range w { + w[i] = workload.Run( + tc.Felixes[0], + fmt.Sprintf("w%d", i), + "default", + fmt.Sprintf("10.65.0.%d", i+2), + "8080", + "tcp", + ) + w[i].ConfigureInInfra(infra) + } + cc = &connectivity.Checker{} + + cc.Expect(connectivity.Some, w[0], w[1]) + cc.Expect(connectivity.Some, w[1], w[0]) + cc.CheckConnectivity() }) }) diff --git a/felix/fv/bpf_policy_dump_test.go b/felix/fv/bpf_policy_dump_test.go index 98bf6800a10..a259c3162a8 100644 --- a/felix/fv/bpf_policy_dump_test.go +++ b/felix/fv/bpf_policy_dump_test.go @@ -19,11 +19,12 @@ package fv_test import ( "os" + "fmt" + "regexp" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "fmt" - api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/api/pkg/lib/numorstring" log "github.com/sirupsen/logrus" @@ -105,47 +106,83 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test policy dump" pol.Spec.Ingress = []api.Rule{{Action: "Allow", Protocol: &protoTCP}} pol.Spec.Ingress[0].Source = api.EntityRule{Nets: srcNets, Ports: []numorstring.Port{numorstring.SinglePort(8055), sportRange}} pol.Spec.Ingress[0].Destination = api.EntityRule{Nets: dstNets, Ports: []numorstring.Port{numorstring.SinglePort(9055), dportRange}} + pol.Spec.Ingress[0].Source.Selector = w[1].NameSelector() pol.Spec.Egress = []api.Rule{{Action: "Deny", Protocol: &protoUDP, NotProtocol: &protoTCP}} pol.Spec.Egress[0].Source = api.EntityRule{NotNets: srcNets, NotPorts: []numorstring.Port{numorstring.SinglePort(8055), sportRange}} pol.Spec.Egress[0].Destination = api.EntityRule{NotNets: dstNets, NotPorts: []numorstring.Port{numorstring.SinglePort(9055), dportRange}} + pol.Spec.Egress[0].Destination.NotSelector = w[1].NameSelector() pol.Spec.Selector = w[0].NameSelector() pol = createPolicy(pol) out := "" ifaceStr := fmt.Sprintf("IfaceName: %s", w[0].InterfaceName) + Eventually(func() string { + out, err = tc.Felixes[0].ExecOutput("calico-bpf", "policy", "dump", w[0].InterfaceName, "ingress") + Expect(err).NotTo(HaveOccurred()) + return out + }, "5s", "200ms").Should(ContainSubstring("Start of policy default.policy-tcp")) + + outStr := string(out) + Expect(outStr).To(ContainSubstring("Start of rule action:\"allow\"")) + Expect(outStr).To(ContainSubstring("IPSets src_ip_set_ids:")) + re := regexp.MustCompile("0x[0-9a-fA-F]+") + ipsetStr := re.FindAllString(outStr, -1) + + // IPSet ID is 64bit. + Expect(len(ipsetStr)).To(Equal(1)) + Expect(len(ipsetStr[0])).To(Equal(18)) + // check ingress policy dump with eBPF assembler code Eventually(func() string { out, err = tc.Felixes[0].ExecOutput("calico-bpf", "policy", "dump", w[0].InterfaceName, "ingress", "-a") Expect(err).NotTo(HaveOccurred()) return out }, "5s", "200ms").Should(ContainSubstring("Start of tier default")) - Expect(string(out)).To(ContainSubstring(ifaceStr)) - Expect(string(out)).To(ContainSubstring("Hook: tc egress")) - Expect(string(out)).To(ContainSubstring("Start of policy default.policy-tcp")) - Expect(string(out)).To(ContainSubstring("Load packet metadata saved by previous program")) - Expect(string(out)).To(ContainSubstring("Save state pointer in register R9")) - Expect(string(out)).To(ContainSubstring("If protocol != tcp, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source not in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest not in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source port is not within any of {8055,100-105}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest port is not within any of {9055,200-205}, skip to next rule")) + + outStr = string(out) + Expect(outStr).To(ContainSubstring(ifaceStr)) + Expect(outStr).To(ContainSubstring("Hook: tc egress")) + Expect(outStr).To(ContainSubstring("Start of policy default.policy-tcp")) + Expect(outStr).To(ContainSubstring("Load packet metadata saved by previous program")) + Expect(outStr).To(ContainSubstring("Save state pointer in register R9")) + Expect(outStr).To(ContainSubstring("If protocol != tcp, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source not in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest not in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source port is not within any of {8055,100-105}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest port is not within any of {9055,200-205}, skip to next rule")) // check egress policy dump with eBPF assembler code out = "" + Eventually(func() string { + out, err = tc.Felixes[0].ExecOutput("calico-bpf", "policy", "dump", w[0].InterfaceName, "egress") + Expect(err).NotTo(HaveOccurred()) + return out + }, "5s", "200ms").Should(ContainSubstring("Start of policy default.policy-tcp")) + + outStr = string(out) + ipsetStr = re.FindAllString(outStr, -1) + Expect(outStr).To(ContainSubstring("Start of rule action:\"deny\"")) + Expect(outStr).To(ContainSubstring("IPSets not_dst_ip_set_ids:")) + // IPSet ID is 64bit. + Expect(len(ipsetStr)).To(Equal(1)) + Expect(len(ipsetStr[0])).To(Equal(18)) + Eventually(func() string { out, err = tc.Felixes[0].ExecOutput("calico-bpf", "policy", "dump", w[0].InterfaceName, "egress", "-a") Expect(err).NotTo(HaveOccurred()) return out }, "5s", "200ms").Should(ContainSubstring("Start of tier default")) - Expect(string(out)).To(ContainSubstring(ifaceStr)) - Expect(string(out)).To(ContainSubstring("Hook: tc ingress")) - Expect(string(out)).To(ContainSubstring("Start of policy default.policy-tcp")) - Expect(string(out)).To(ContainSubstring("Load packet metadata saved by previous program")) - Expect(string(out)).To(ContainSubstring("Save state pointer in register R9")) - Expect(string(out)).To(ContainSubstring("If protocol == tcp, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source port is within any of {8055,100-105}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest port is within any of {9055,200-205}, skip to next rule")) + + outStr = string(out) + Expect(outStr).To(ContainSubstring(ifaceStr)) + Expect(outStr).To(ContainSubstring("Hook: tc ingress")) + Expect(outStr).To(ContainSubstring("Start of policy default.policy-tcp")) + Expect(outStr).To(ContainSubstring("Load packet metadata saved by previous program")) + Expect(outStr).To(ContainSubstring("Save state pointer in register R9")) + Expect(outStr).To(ContainSubstring("If protocol == tcp, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source port is within any of {8055,100-105}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest port is within any of {9055,200-205}, skip to next rule")) // Test calico-bpf policy dump all with eBPF assembler code out = "" @@ -154,18 +191,19 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test policy dump" Expect(err).NotTo(HaveOccurred()) return out }, "5s", "200ms").Should(ContainSubstring("Start of tier default")) - Expect(string(out)).To(ContainSubstring("Hook: tc ingress")) - Expect(string(out)).To(ContainSubstring("Hook: tc egress")) - Expect(string(out)).To(ContainSubstring("If protocol == tcp, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If protocol != tcp, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source port is within any of {8055,100-105}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest port is within any of {9055,200-205}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source not in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest not in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source port is not within any of {8055,100-105}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest port is not within any of {9055,200-205}, skip to next rule")) + outStr = string(out) + Expect(outStr).To(ContainSubstring("Hook: tc ingress")) + Expect(outStr).To(ContainSubstring("Hook: tc egress")) + Expect(outStr).To(ContainSubstring("If protocol == tcp, skip to next rule")) + Expect(outStr).To(ContainSubstring("If protocol != tcp, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source port is within any of {8055,100-105}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest port is within any of {9055,200-205}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source not in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest not in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source port is not within any of {8055,100-105}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest port is not within any of {9055,200-205}, skip to next rule")) }) It("should dump policy debug information with ICMP", func() { @@ -195,15 +233,16 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test policy dump" Expect(err).NotTo(HaveOccurred()) return out }, "5s", "200ms").Should(ContainSubstring("Start of tier default")) - Expect(string(out)).To(ContainSubstring(ifaceStr)) - Expect(string(out)).To(ContainSubstring("Hook: tc egress")) - Expect(string(out)).To(ContainSubstring("Start of policy default.policy-icmp")) - Expect(string(out)).To(ContainSubstring("Load packet metadata saved by previous program")) - Expect(string(out)).To(ContainSubstring("Save state pointer in register R9")) - Expect(string(out)).To(ContainSubstring("If protocol != icmp, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If ICMP type != 10 or code != 12, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source not in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest not in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) + outStr := string(out) + Expect(outStr).To(ContainSubstring(ifaceStr)) + Expect(outStr).To(ContainSubstring("Hook: tc egress")) + Expect(outStr).To(ContainSubstring("Start of policy default.policy-icmp")) + Expect(outStr).To(ContainSubstring("Load packet metadata saved by previous program")) + Expect(outStr).To(ContainSubstring("Save state pointer in register R9")) + Expect(outStr).To(ContainSubstring("If protocol != icmp, skip to next rule")) + Expect(outStr).To(ContainSubstring("If ICMP type != 10 or code != 12, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source not in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest not in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) // check egress policy dump with eBPF assembler code out = "" @@ -212,14 +251,15 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Felix bpf test policy dump" Expect(err).NotTo(HaveOccurred()) return out }, "5s", "200ms").Should(ContainSubstring("Start of tier default")) - Expect(string(out)).To(ContainSubstring(ifaceStr)) - Expect(string(out)).To(ContainSubstring("Hook: tc ingress")) - Expect(string(out)).To(ContainSubstring("Start of policy default.policy-icmp")) - Expect(string(out)).To(ContainSubstring("Load packet metadata saved by previous program")) - Expect(string(out)).To(ContainSubstring("Save state pointer in register R9")) - Expect(string(out)).To(ContainSubstring("If protocol == icmp, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If ICMP type == 10 and code == 12, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If source in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) - Expect(string(out)).To(ContainSubstring("If dest in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) + outStr = string(out) + Expect(outStr).To(ContainSubstring(ifaceStr)) + Expect(outStr).To(ContainSubstring("Hook: tc ingress")) + Expect(outStr).To(ContainSubstring("Start of policy default.policy-icmp")) + Expect(outStr).To(ContainSubstring("Load packet metadata saved by previous program")) + Expect(outStr).To(ContainSubstring("Save state pointer in register R9")) + Expect(outStr).To(ContainSubstring("If protocol == icmp, skip to next rule")) + Expect(outStr).To(ContainSubstring("If ICMP type == 10 and code == 12, skip to next rule")) + Expect(outStr).To(ContainSubstring("If source in {11.0.0.8/32,10.0.0.8/32}, skip to next rule")) + Expect(outStr).To(ContainSubstring("If dest in {12.0.0.8/32,13.0.0.8/32}, skip to next rule")) }) }) diff --git a/felix/fv/bpf_test.go b/felix/fv/bpf_test.go index 28aa10301cc..9258e2ef115 100644 --- a/felix/fv/bpf_test.go +++ b/felix/fv/bpf_test.go @@ -53,6 +53,7 @@ import ( "github.com/projectcalico/calico/felix/bpf" "github.com/projectcalico/calico/felix/bpf/conntrack" "github.com/projectcalico/calico/felix/bpf/ifstate" + "github.com/projectcalico/calico/felix/bpf/ipsets" "github.com/projectcalico/calico/felix/bpf/maps" "github.com/projectcalico/calico/felix/bpf/nat" "github.com/projectcalico/calico/felix/bpf/proxy" @@ -408,6 +409,15 @@ func describeBPFTests(opts ...bpfTestOpt) bool { options.ExtraEnvVars["FELIX_BPFExtToServiceConnmark"] = "0x80" options.ExtraEnvVars["FELIX_HEALTHENABLED"] = "true" options.ExtraEnvVars["FELIX_BPFDSROptoutCIDRs"] = "245.245.0.0/16,beaf::dead/64" + if testOpts.tunnel == "wireguard" { + options.ExtraEnvVars["FELIX_BPFREDIRECTTOPEERFROML3DEVICE"] = "true" + } + if testOpts.tunnel == "ipip" && testOpts.protocol != "udp" { + // Some tests run with tcpdump in udp case. We make sure that + // the redirection does not affect connectivity, but we exclude + // those tests. It is too coarse, but the simplest. + options.ExtraEnvVars["FELIX_BPFREDIRECTTOPEERFROML3DEVICE"] = "true" + } if !testOpts.ipv6 { options.ExtraEnvVars["FELIX_HEALTHHOST"] = "0.0.0.0" } else { @@ -602,13 +612,13 @@ func describeBPFTests(opts ...bpfTestOpt) bool { Describe("with custom IptablesMarkMask", func() { BeforeEach(func() { // Disable core dumps, we know we're about to cause a panic. - options.ExtraEnvVars["GOTRACEBACK"] = "" + options.FelixCoreDumpsEnabled = false felixPanicExpected = true }) It("0xffff000 not covering BPF bits should panic", func() { felixPanicExpected = true - panicC := tc.Felixes[0].WatchStdoutFor(regexp.MustCompile("PANIC.*IptablesMarkMask doesn't cover bits that are used")) + panicC := tc.Felixes[0].WatchStdoutFor(regexp.MustCompile("PANIC.*IptablesMarkMask/NftablesMarkMask doesn't cover bits that are used")) fc, err := calicoClient.FelixConfigurations().Get(context.Background(), "default", options2.GetOptions{}) felixConfigExists := err == nil @@ -618,6 +628,7 @@ func describeBPFTests(opts ...bpfTestOpt) bool { fc.Name = "default" mark := uint32(0x0ffff000) fc.Spec.IptablesMarkMask = &mark + fc.Spec.NftablesMarkMask = &mark if felixConfigExists { _, err = calicoClient.FelixConfigurations().Update(context.Background(), fc, options2.SetOptions{}) } else { @@ -639,6 +650,7 @@ func describeBPFTests(opts ...bpfTestOpt) bool { fc.Name = "default" mark := uint32(0xfff00000) fc.Spec.IptablesMarkMask = &mark + fc.Spec.NftablesMarkMask = &mark if felixConfigExists { _, err = calicoClient.FelixConfigurations().Update(context.Background(), fc, options2.SetOptions{}) } else { @@ -693,11 +705,11 @@ func describeBPFTests(opts ...bpfTestOpt) bool { mustGetMapIDByPath := func(felix *infrastructure.Felix, filename string) int { var mapID int - Eventually(func() error { + EventuallyWithOffset(1, func() error { var err error mapID, err = getMapIDByPath(felix, filename) return err - }, "10s").ShouldNot(HaveOccurred()) + }, "10s", "300ms").ShouldNot(HaveOccurred()) return mapID } @@ -969,6 +981,22 @@ func describeBPFTests(opts ...bpfTestOpt) bool { cc.ResetExpectations() } }) + + It("should respond back to host is the original traffic came from the host", func() { + if NFTMode() || testOpts.ipv6 { + return + } + + By("Setting up istio-like rules that SNAT host as link-local IP") + + tc.Felixes[0].Exec("iptables", "-t", "nat", "-A", "POSTROUTING", "-d", w[0].IP, "-j", + "SNAT", "--to-source", "169.254.7.127") + + By("Testing connectivity from host to pod") + + cc.Expect(Some, hostW, w[0], ExpectWithSrcIPs("169.254.7.127")) + cc.CheckConnectivity() + }) } if testOpts.nonProtoTests { @@ -1236,12 +1264,11 @@ func describeBPFTests(opts ...bpfTestOpt) bool { Expect(err).NotTo(HaveOccurred()) if !options.TestManagesBPF { ensureAllNodesBPFProgramsAttached(tc.Felixes) - felixReady := func(f *infrastructure.Felix) int { - return healthStatus(containerIP(f.Container), "9099", "readiness") - } - for _, f := range tc.Felixes { - Eventually(felixReady(f), "10s", "500ms").Should(BeGood()) + felixReady := func() int { + return healthStatus(containerIP(f.Container), "9099", "readiness") + } + Eventually(felixReady, "10s", "500ms").Should(BeGood()) } } } @@ -4083,7 +4110,7 @@ func describeBPFTests(opts ...bpfTestOpt) bool { }) It("should have connectivity to service backend", func() { - tcpdump := tc.Felixes[0].AttachTCPDump(w[0][0].InterfaceName) + tcpdump := w[0][0].AttachTCPDump() tcpdump.SetLogEnabled(true) tcpdump.AddMatcher("mtu-1300", regexp.MustCompile("mtu 1300")) tcpdump.Start("-vvv", "icmp", "or", "icmp6") @@ -5232,6 +5259,20 @@ func dumpIfStateMap(felix *infrastructure.Felix) ifstate.MapMem { return m } +func dumpIPSetsMap(felix *infrastructure.Felix) ipsets.MapMem { + im := ipsets.Map() + m := make(ipsets.MapMem) + dumpBPFMap(felix, im, ipsets.MapMemIter(m)) + return m +} + +func dumpIPSets6Map(felix *infrastructure.Felix) ipsets.MapMemV6 { + im := ipsets.MapV6() + m := make(ipsets.MapMemV6) + dumpBPFMap(felix, im, ipsets.MapMemV6Iter(m)) + return m +} + func ensureAllNodesBPFProgramsAttached(felixes []*infrastructure.Felix, ifacesExtra ...string) { for _, felix := range felixes { ensureBPFProgramsAttachedOffset(2, felix, ifacesExtra...) @@ -5593,7 +5634,7 @@ func checkServiceRoute(felix *infrastructure.Felix, ip string) bool { err error ) - if felix.TopologyOptions.EnableIPv6 { + if strings.Contains(ip, ":") && felix.TopologyOptions.EnableIPv6 { out, err = felix.ExecOutput("ip", "-6", "route") } else { out, err = felix.ExecOutput("ip", "route") diff --git a/felix/fv/containers/containers.go b/felix/fv/containers/containers.go index 8c420b7396a..9c40e159240 100644 --- a/felix/fv/containers/containers.go +++ b/felix/fv/containers/containers.go @@ -16,6 +16,7 @@ package containers import ( "bufio" + "bytes" "encoding/json" "fmt" "io" @@ -51,11 +52,12 @@ type Container struct { runCmd *exec.Cmd Stdin io.WriteCloser - mutex sync.Mutex - binaries set.Set[string] - stdoutWatches []*watch - stderrWatches []*watch - dataRaces []string + mutex sync.Mutex + binaries set.Set[string] + stdoutWatches []*watch + stderrWatches []*watch + dataRaces []string + raceDetectionDisabled bool logFinished sync.WaitGroup dropAllLogs bool @@ -254,8 +256,8 @@ func RunWithFixedName(name string, opts RunOpts, args ...string) (c *Container) // Merge container's output into our own logging. c.logFinished.Add(2) - go c.copyOutputToLog("stdout", stdout, &c.logFinished, &c.stdoutWatches) - go c.copyOutputToLog("stderr", stderr, &c.logFinished, &c.stderrWatches) + go c.copyOutputToLog("stdout", stdout, &c.logFinished, &c.stdoutWatches, nil) + go c.copyOutputToLog("stderr", stderr, &c.logFinished, &c.stderrWatches, nil) // Note: it might take a long time for the container to start running, e.g. if the image // needs to be downloaded. @@ -322,8 +324,8 @@ func (c *Container) Start() { // Merge container's output into our own logging. c.logFinished.Add(2) - go c.copyOutputToLog("stdout", stdout, &c.logFinished, &c.stdoutWatches) - go c.copyOutputToLog("stderr", stderr, &c.logFinished, nil) + go c.copyOutputToLog("stdout", stdout, &c.logFinished, &c.stdoutWatches, nil) + go c.copyOutputToLog("stderr", stderr, &c.logFinished, nil, nil) c.WaitUntilRunning() @@ -340,7 +342,7 @@ func (c *Container) Remove() { log.WithField("container", c).Info("Removed container.") } -func (c *Container) copyOutputToLog(streamName string, stream io.Reader, done *sync.WaitGroup, watches *[]*watch) { +func (c *Container) copyOutputToLog(streamName string, stream io.Reader, done *sync.WaitGroup, watches *[]*watch, extraWriter io.Writer) { defer done.Done() scanner := bufio.NewScanner(stream) scanner.Buffer(nil, 10*1024*1024) // Increase maximum buffer size (but don't pre-alloc). @@ -370,6 +372,12 @@ func (c *Container) copyOutputToLog(streamName string, stream io.Reader, done *s for scanner.Scan() { line := scanner.Text() + if extraWriter != nil { + _, err := extraWriter.Write([]byte(line + "\n")) + if err != nil { + log.WithError(err).Error("Failed to write to extra writer.") + } + } if c.ignoreEmptyLines && strings.Trim(line, " \r\n\t") == "" { continue @@ -438,9 +446,21 @@ func (c *Container) DataRaces() []string { c.mutex.Lock() defer c.mutex.Unlock() + if c.raceDetectionDisabled { + return nil + } return c.dataRaces } +// DisableRaceDetector disables race detection for this test. This is useful +// for testing the race detection logic. +func (c *Container) DisableRaceDetector() { + c.mutex.Lock() + defer c.mutex.Unlock() + + c.raceDetectionDisabled = true +} + func (c *Container) DockerInspect(format string) string { inspectCmd := utils.Command("docker", "inspect", "--format="+format, @@ -662,17 +682,16 @@ func (c *Container) ExecOutput(args ...string) (string, error) { } var wg sync.WaitGroup wg.Add(1) - go c.copyOutputToLog("exec-err", stderr, &wg, nil) - defer wg.Wait() + var errBuf bytes.Buffer + go c.copyOutputToLog("exec-err", stderr, &wg, nil, &errBuf) out, err := cmd.Output() + stdoutStr := string(out) + wg.Wait() // Wait for the stderr copy to finish so errBuf is safe to read. if err != nil { - if out == nil { - return "", fmt.Errorf("command failed with no output %q: %w", cmd, err) - } - outStr := string(out) - return outStr, fmt.Errorf("command failed %q: %w output=%q", cmd, err, outStr) + stderrStr := errBuf.String() + return stdoutStr, fmt.Errorf("command failed %q with stdout=%q stderr=%q: %w", cmd, stdoutStr, stderrStr, err) } - return string(out), nil + return stdoutStr, nil } func (c *Container) ExecOutputFn(args ...string) func() (string, error) { @@ -761,7 +780,11 @@ func (c *Container) NFTSetSizes() map[string]int { numMembers := map[string]int{} names := c.IPSetNames() for _, name := range names { - numMembers[name] = c.NumNFTSetMembers(4, name) + if strings.HasPrefix(name, "cali60") { + numMembers[name] = c.NumNFTSetMembers(6, name) + } else { + numMembers[name] = c.NumNFTSetMembers(4, name) + } } return numMembers } @@ -782,7 +805,10 @@ func (c *Container) NumNFTSetMembers(ipVersion int, setName string) int { ip = "ip6" } out, err := c.ExecOutput("nft", "--json", "list", "set", ip, "calico", setName) - Expect(err).NotTo(HaveOccurred()) + if err != nil { + log.WithError(err).Warn("Failed to list nft IP set.") + return -1 + } type nftResp struct { Nftables []map[string]interface{} `json:"nftables"` @@ -820,7 +846,14 @@ func (c *Container) IPSetNames() []string { } func (c *Container) nftablesSetNames() []string { - out, err := c.ExecOutput("nft", "list", "sets", "ip") + // Get the set names for both IPv4 and IPv6. + ipv4Names := c.nftablesSetNamesForVersion("ip") + ipv6Names := c.nftablesSetNamesForVersion("ip6") + return append(ipv4Names, ipv6Names...) +} + +func (c *Container) nftablesSetNamesForVersion(ver string) []string { + out, err := c.ExecOutput("nft", "list", "sets", ver) Expect(err).NotTo(HaveOccurred(), out) var names []string for _, line := range strings.Split(out, "\n") { diff --git a/felix/fv/donottrack_test.go b/felix/fv/donottrack_test.go index 792359989bf..cce665d1182 100644 --- a/felix/fv/donottrack_test.go +++ b/felix/fv/donottrack_test.go @@ -19,6 +19,7 @@ package fv_test import ( "context" "fmt" + "strings" "time" . "github.com/projectcalico/calico/felix/fv/connectivity" @@ -46,6 +47,8 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ do-not-track policy tests; client client.Interface cc *Checker externalClient *containers.Container + ctx context.Context + cancel context.CancelFunc ) BeforeEach(func() { @@ -158,6 +161,107 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ do-not-track policy tests; cc.CheckConnectivityOffset(1) } + testDonotTrackPolicy := func(iface string) { + // This test covers both normal connectivity and failsafe connectivity. We combine the + // tests because we rely on the changes of normal connectivity at each step to make sure + // that the policy has actually flowed through to the dataplane. + + By("having only failsafe connectivity to start with") + expectFailSafeOnlyConnectivity() + + if BPFMode() { + expectFailSafeOnlyConnectivity(ExpectWithIPVersion(6)) + By("Having no Linux IP sets") + Consistently(tc.Felixes[0].IPSetNames, "2s", "1s").Should(BeEmpty()) + } + + host0Selector := fmt.Sprintf("name == '%s-%s'", iface, tc.Felixes[0].Name) + host1Selector := fmt.Sprintf("name == '%s-%s'", iface, tc.Felixes[1].Name) + + By("Having connectivity after installing bidirectional policies") + host0Pol := createDonotTrackPolicy("host-0-pol", host0Selector, host1Selector, client, ctx) + _ = createDonotTrackPolicy("host-1-pol", host1Selector, host0Selector, client, ctx) + + if iface == "bond0" { + Consistently(xdpProgramAttached(tc.Felixes[0], "bond0"), "2s", "1s").Should(BeFalse()) + Consistently(xdpProgramAttached(tc.Felixes[1], "bond0"), "2s", "1s").Should(BeFalse()) + Eventually(xdpProgramAttached(tc.Felixes[0], "eth0"), "10s", "1s").Should(BeTrue()) + Eventually(xdpProgramAttached(tc.Felixes[1], "eth0"), "10s", "1s").Should(BeTrue()) + } + + expectFullConnectivity() + if BPFMode() { + expectFullConnectivity(ExpectWithIPVersion(6)) + By("Having a Linux IP set for the egress policy") + + elems := []string{ + utils.IPSetNameForSelector(4, host1Selector), + utils.IPSetNameForSelector(6, host1Selector), + } + if NFTMode() { + // NFT uses a different prefixing scheme, since the ":" character is not allowed. + // e.g., cali40- instead of cali40: + for i, elem := range elems { + elems[i] = strings.Replace(elem, ":", "-", 1) + } + } + Expect(tc.Felixes[0].IPSetNames()).To(ContainElements(elems)) + } + + By("Having only failsafe connectivity after replacing host-0's egress rules with Deny") + // Since there's no conntrack, removing rules in one direction is enough to prevent + // connectivity in either direction. + host0Pol.Spec.Egress = []api.Rule{ + { + Action: api.Deny, + Destination: api.EntityRule{ + Selector: host0Selector, + }, + }, + } + host0Pol, err := client.GlobalNetworkPolicies().Update(ctx, host0Pol, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) + + expectFailSafeOnlyConnectivityWithHost0() + if BPFMode() { + expectFailSafeOnlyConnectivityWithHost0(ExpectWithIPVersion(6)) + } + + By("Having full connectivity after putting them back") + host0Pol.Spec.Egress = []api.Rule{ + { + Action: api.Allow, + Destination: api.EntityRule{ + Selector: host1Selector, + }, + }, + } + host0Pol, err = client.GlobalNetworkPolicies().Update(ctx, host0Pol, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) + + expectFullConnectivity() + if BPFMode() { + expectFullConnectivity(ExpectWithIPVersion(6)) + } + + By("Having only failsafe connectivity after replacing host-0's ingress rules with Deny") + host0Pol.Spec.Ingress = []api.Rule{ + { + Action: api.Deny, + Destination: api.EntityRule{ + Selector: host0Selector, + }, + }, + } + host0Pol, err = client.GlobalNetworkPolicies().Update(ctx, host0Pol, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) + + expectFailSafeOnlyConnectivityWithHost0() + if BPFMode() { + expectFailSafeOnlyConnectivityWithHost0(ExpectWithIPVersion(6)) + } + } + It("before adding policy, should have connectivity between hosts", func() { expectFullConnectivity() if BPFMode() { @@ -166,11 +270,6 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ do-not-track policy tests; }) Context("after adding host endpoints", func() { - var ( - ctx context.Context - cancel context.CancelFunc - ) - BeforeEach(func() { // Make sure our new host endpoints don't cut felix off from the datastore. err := infra.AddAllowToDatastore("host-endpoint=='true'") @@ -179,21 +278,11 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ do-not-track policy tests; ctx, cancel = context.WithTimeout(context.Background(), 50*time.Second) for _, f := range tc.Felixes { - hep := api.NewHostEndpoint() - hep.Name = "eth0-" + f.Name - hep.Labels = map[string]string{ - "name": hep.Name, - "host-endpoint": "true", - } - hep.Spec.Node = f.Hostname - hep.Spec.InterfaceName = "eth0" - hep.Spec.ExpectedIPs = []string{f.IP, f.IPv6} - _, err := client.HostEndpoints().Create(ctx, hep, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) + createHostEndpoint(f, "eth0", []string{f.IP, f.IPv6}, client, ctx) } if BPFMode() { - ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, nil) - ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, nil) + ensureRightIFStateFlags(tc.Felixes[0], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgHEP, nil) + ensureRightIFStateFlags(tc.Felixes[1], ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgHEP, nil) } }) @@ -202,133 +291,147 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ do-not-track policy tests; }) It("should implement untracked policy correctly", func() { - // This test covers both normal connectivity and failsafe connectivity. We combine the - // tests because we rely on the changes of normal connectivity at each step to make sure - // that the policy has actually flowed through to the dataplane. - - By("having only failsafe connectivity to start with") - expectFailSafeOnlyConnectivity() - - if BPFMode() { - expectFailSafeOnlyConnectivity(ExpectWithIPVersion(6)) - By("Having no Linux IP sets") - Consistently(tc.Felixes[0].IPSetNames, "2s", "1s").Should(BeEmpty()) - } - - host0Selector := fmt.Sprintf("name == 'eth0-%s'", tc.Felixes[0].Name) - host1Selector := fmt.Sprintf("name == 'eth0-%s'", tc.Felixes[1].Name) - - By("Having connectivity after installing bidirectional policies") - host0Pol := api.NewGlobalNetworkPolicy() - host0Pol.Name = "host-0-pol" - host0Pol.Spec.Selector = host0Selector - host0Pol.Spec.DoNotTrack = true - host0Pol.Spec.ApplyOnForward = true - host0Pol.Spec.Ingress = []api.Rule{ - { - Action: api.Allow, - Source: api.EntityRule{ - Selector: host1Selector, - }, - }, - } - host0Pol.Spec.Egress = []api.Rule{ - { - Action: api.Allow, - Destination: api.EntityRule{ - Selector: host1Selector, - }, - }, - } - host0Pol, err := client.GlobalNetworkPolicies().Create(ctx, host0Pol, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) + testDonotTrackPolicy("eth0") + }) - host1Pol := api.NewGlobalNetworkPolicy() - host1Pol.Name = "host-1-pol" - host1Pol.Spec.Selector = host1Selector - host1Pol.Spec.DoNotTrack = true - host1Pol.Spec.ApplyOnForward = true - host1Pol.Spec.Ingress = []api.Rule{ - { - Action: api.Allow, - Source: api.EntityRule{ - Selector: host0Selector, - }, - }, - } - host1Pol.Spec.Egress = []api.Rule{ - { - Action: api.Allow, - Destination: api.EntityRule{ - Selector: host0Selector, - }, - }, - } - host1Pol, err = client.GlobalNetworkPolicies().Create(ctx, host1Pol, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) + if BPFMode() { + Describe("with a custom map size", func() { + BeforeEach(func() { + newRtSize := 1000 + newNATFeSize := 2000 + newNATBeSize := 3000 + newNATAffSize := 4000 + newIpSetMapSize := 5000 + newCtMapSize := 6000 + infrastructure.UpdateFelixConfiguration(client, func(cfg *api.FelixConfiguration) { + cfg.Spec.BPFMapSizeRoute = &newRtSize + cfg.Spec.BPFMapSizeNATFrontend = &newNATFeSize + cfg.Spec.BPFMapSizeNATBackend = &newNATBeSize + cfg.Spec.BPFMapSizeNATAffinity = &newNATAffSize + cfg.Spec.BPFMapSizeIPSets = &newIpSetMapSize + cfg.Spec.BPFMapSizeConntrack = &newCtMapSize + }) + }) + + It("should implement untracked policy correctly", func() { + testDonotTrackPolicy("eth0") + }) + }) + } + }) - expectFullConnectivity() - if BPFMode() { - expectFullConnectivity(ExpectWithIPVersion(6)) - By("Having a Linux IP set for the egress policy") - Expect(tc.Felixes[0].IPSetNames()).To(ContainElements( - utils.IPSetNameForSelector(4, host1Selector), - utils.IPSetNameForSelector(6, host1Selector), - )) - } + Context("after adding eth0 to a bond interface", func() { + if !BPFMode() { + return + } - By("Having only failsafe connectivity after replacing host-0's egress rules with Deny") - // Since there's no conntrack, removing rules in one direction is enough to prevent - // connectivity in either direction. - host0Pol.Spec.Egress = []api.Rule{ - { - Action: api.Deny, - Destination: api.EntityRule{ - Selector: host0Selector, - }, - }, - } - host0Pol, err = client.GlobalNetworkPolicies().Update(ctx, host0Pol, options.SetOptions{}) + BeforeEach(func() { + // Make sure our new host endpoints don't cut felix off from the datastore. + err := infra.AddAllowToDatastore("host-endpoint=='true'") Expect(err).NotTo(HaveOccurred()) - expectFailSafeOnlyConnectivityWithHost0() - if BPFMode() { - expectFailSafeOnlyConnectivityWithHost0(ExpectWithIPVersion(6)) - } + ctx, cancel = context.WithTimeout(context.Background(), 50*time.Second) + for _, felix := range tc.Felixes { + // recreate those after moving the IP. + defaultRoute, err := felix.ExecOutput("ip", "route", "show", "default") + Expect(err).NotTo(HaveOccurred()) + lines := strings.Split(strings.Trim(defaultRoute, "\n "), "\n") + Expect(lines).To(HaveLen(1)) + defaultRouteArgs := strings.Split(strings.Replace(lines[0], "eth0", "bond0", -1), " ") - By("Having full connectivity after putting them back") - host0Pol.Spec.Egress = []api.Rule{ - { - Action: api.Allow, - Destination: api.EntityRule{ - Selector: host1Selector, - }, - }, - } - host0Pol, err = client.GlobalNetworkPolicies().Update(ctx, host0Pol, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) + // Assuming the subnet route will be "proto kernel" and that will be the only such route. + subnetRoute, err := felix.ExecOutput("ip", "route", "show", "proto", "kernel") + Expect(err).NotTo(HaveOccurred()) + lines = strings.Split(strings.Trim(subnetRoute, "\n "), "\n") + Expect(lines).To(HaveLen(1), "expected only one proto kernel route, has docker's routing set-up changed?") + subnetArgs := strings.Split(strings.Replace(lines[0], "eth0", "bond0", -1), " ") - expectFullConnectivity() - if BPFMode() { - expectFullConnectivity(ExpectWithIPVersion(6)) - } + //Move IPv6 + defaultRoute6, err := felix.ExecOutput("ip", "-6", "route", "show", "default") + Expect(err).NotTo(HaveOccurred()) + lines = strings.Split(strings.Trim(defaultRoute6, "\n "), "\n") + Expect(lines).To(HaveLen(1)) + defaultRoute6Args := strings.Split(strings.Replace(lines[0], "eth0", "bond0", -1), " ") - By("Having only failsafe connectivity after replacing host-0's ingress rules with Deny") - host0Pol.Spec.Ingress = []api.Rule{ - { - Action: api.Deny, - Destination: api.EntityRule{ - Selector: host0Selector, - }, - }, + // Assuming the subnet route will be "proto kernel" and that will be the only such route. + subnetRoute6, err := felix.ExecOutput("ip", "-6", "route", "show", "proto", "kernel") + Expect(err).NotTo(HaveOccurred()) + lines = strings.Split(strings.Trim(subnetRoute6, "\n "), "\n") + subnet6Args := strings.Split(strings.Replace(lines[0], "eth0", "bond0", -1), " ") + + felix.Exec("ip", "addr", "del", felix.IP, "dev", "eth0") + ip6WithSubnet := felix.IPv6 + "/" + felix.GetIPv6Prefix() + felix.Exec("ip", "-6", "addr", "del", ip6WithSubnet, "dev", "eth0") + + felix.Exec("ip", "link", "add", "dev", "bond0", "type", "bond") + felix.Exec("ip", "link", "set", "dev", "eth0", "down") + felix.Exec("ip", "link", "set", "dev", "eth0", "master", "bond0") + felix.Exec("ip", "link", "set", "dev", "eth0", "up") + felix.Exec("ip", "link", "set", "dev", "bond0", "up") + + ipWithSubnet := felix.IP + "/" + felix.GetIPPrefix() + felix.Exec("ip", "addr", "add", ipWithSubnet, "dev", "bond0") + felix.Exec(append([]string{"ip", "r", "add"}, defaultRouteArgs...)...) + felix.Exec(append([]string{"ip", "r", "replace"}, subnetArgs...)...) + + felix.Exec("ip", "-6", "addr", "add", ip6WithSubnet, "dev", "bond0") + felix.Exec(append([]string{"ip", "-6", "r", "add"}, defaultRoute6Args...)...) + felix.Exec(append([]string{"ip", "-6", "r", "replace"}, subnet6Args...)...) + + ensureRightIFStateFlags(felix, ifstate.FlgIPv4Ready|ifstate.FlgIPv6Ready, ifstate.FlgBondSlave, map[string]uint32{"bond0": ifstate.FlgIPv4Ready | ifstate.FlgIPv6Ready | ifstate.FlgBond}) + createHostEndpoint(felix, "bond0", []string{felix.IP, felix.IPv6}, client, ctx) } - host0Pol, err = client.GlobalNetworkPolicies().Update(ctx, host0Pol, options.SetOptions{}) - Expect(err).NotTo(HaveOccurred()) + }) - expectFailSafeOnlyConnectivityWithHost0() - if BPFMode() { - expectFailSafeOnlyConnectivityWithHost0(ExpectWithIPVersion(6)) - } + AfterEach(func() { + cancel() + }) + It("should implement untracked policy correctly", func() { + testDonotTrackPolicy("bond0") }) + }) + }) + +func createHostEndpoint(f *infrastructure.Felix, iface string, + expectedIPs []string, client client.Interface, ctx context.Context) { + hep := api.NewHostEndpoint() + hep.Name = iface + "-" + f.Name + hep.Labels = map[string]string{ + "name": hep.Name, + "host-endpoint": "true", + } + hep.Spec.Node = f.Hostname + hep.Spec.InterfaceName = iface + hep.Spec.ExpectedIPs = expectedIPs + _, err := client.HostEndpoints().Create(ctx, hep, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) +} + +func createDonotTrackPolicy(name, selector, dstSelector string, client client.Interface, ctx context.Context) *api.GlobalNetworkPolicy { + pol := api.NewGlobalNetworkPolicy() + pol.Name = name + pol.Spec.Selector = selector + pol.Spec.DoNotTrack = true + pol.Spec.ApplyOnForward = true + pol.Spec.Ingress = []api.Rule{ + { + Action: api.Allow, + Source: api.EntityRule{ + Selector: dstSelector, + }, + }, + } + pol.Spec.Egress = []api.Rule{ + { + Action: api.Allow, + Destination: api.EntityRule{ + Selector: dstSelector, + }, + }, + } + pol, err := client.GlobalNetworkPolicies().Create(ctx, pol, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) + return pol +} diff --git a/felix/fv/etcd_restart_test.go b/felix/fv/etcd_restart_test.go index 7f1234de23a..a5bf6b6a565 100644 --- a/felix/fv/etcd_restart_test.go +++ b/felix/fv/etcd_restart_test.go @@ -21,6 +21,7 @@ import ( "fmt" "regexp" "strings" + "syscall" "time" "github.com/projectcalico/calico/felix/fv/connectivity" @@ -28,7 +29,6 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" @@ -39,6 +39,7 @@ import ( "github.com/projectcalico/calico/felix/fv/utils" "github.com/projectcalico/calico/felix/fv/workload" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/netlinkutils" ) var _ = Context("etcd connection interruption", func() { @@ -60,7 +61,11 @@ var _ = Context("etcd connection interruption", func() { // Wait until the tunl0 device appears; it is created when felix inserts the ipip module // into the kernel. Eventually(func() error { - links, err := netlink.LinkList() + nlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) + if err != nil { + return err + } + links, err := netlinkutils.LinkListRetryEINTR(nlHandle) if err != nil { return err } diff --git a/felix/fv/fv_infra_test.go b/felix/fv/fv_infra_test.go index ef94df9e16e..db42699cd34 100644 --- a/felix/fv/fv_infra_test.go +++ b/felix/fv/fv_infra_test.go @@ -27,6 +27,7 @@ import ( . "github.com/onsi/gomega" log "github.com/sirupsen/logrus" + "github.com/projectcalico/calico/felix/fv/utils" "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" "github.com/projectcalico/calico/felix/fv/connectivity" @@ -184,11 +185,23 @@ var _ = infrastructure.DatastoreDescribe("Container self tests", dir, err := os.ReadDir("/tmp") Expect(err).NotTo(HaveOccurred()) name := "" + var filesToClean []string for _, f := range dir { if strings.Contains(f.Name(), "core_"+tc.Felixes[0].Hostname) { name = f.Name() + filesToClean = append(filesToClean, name) } } + defer func() { + // The core files get owned by root, use temporary privileged container to clean them up. + for _, s := range filesToClean { + utils.Run("docker", "run", + "--rm", + "-v", "/tmp:/tmp", + "--privileged", + "--entrypoint", "rm", utils.Config.FelixImage, "/tmp/"+s) + } + }() Expect(name).NotTo(Equal(""), "Couldn't find core file") s, err := os.Stat("/tmp/" + name) Expect(err).NotTo(HaveOccurred()) @@ -204,6 +217,7 @@ var _ = infrastructure.DatastoreDescribe("Container self tests", if os.Getenv("FV_RACE_DETECTOR_ENABLED") == "true" { It("should detect a race", func() { Eventually(tc.Felixes[0].DataRaces).ShouldNot(BeEmpty()) + tc.Felixes[0].DisableRaceDetector() }) } else { It("should not detect a race because race detector is disabled", func() { diff --git a/felix/fv/health_test.go b/felix/fv/health_test.go index 1a5bdb94e8c..5351e4a48e3 100644 --- a/felix/fv/health_test.go +++ b/felix/fv/health_test.go @@ -355,7 +355,7 @@ var _ = Describe("_HEALTH_ _BPF-SAFE_ health tests", func() { }) It("typha should not report live", func() { - Consistently(typhaLiveness(), "10s", "1s").ShouldNot(BeGood()) + Consistently(typhaLiveness, "10s", "1s").ShouldNot(BeGood()) }) }) diff --git a/felix/fv/hostendpoints_test.go b/felix/fv/hostendpoints_test.go index acd81ada0b0..db71f3a5d03 100644 --- a/felix/fv/hostendpoints_test.go +++ b/felix/fv/hostendpoints_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -252,7 +252,7 @@ func describeHostEndpointTests(getInfra infrastructure.InfraFactory, allInterfac Expect(err).NotTo(HaveOccurred()) if bpfEnabled { - Eventually(f.NumTCBPFProgsEth0, "5s", "200ms").Should(Equal(2)) + Eventually(f.NumTCBPFProgsEth0, "30s", "200ms").Should(Equal(2)) } } @@ -304,20 +304,35 @@ func describeHostEndpointTests(getInfra infrastructure.InfraFactory, allInterfac cc.CheckConnectivity() }) - It("should allow felixes[0] => felixes[1] traffic if ingress and egress policies are in place", func() { + It("should allow containers.Felix[0] => containers.Felix[1] traffic if ingress and egress policies are in place", func() { + // Create a "security" tier. We had a bug in Enterprise Felix that wrongly + // hardcoded the "default" tier name, and most of the tests in this file use + // "default" because of having originated in OSS. This test is modified to + // use a non-default tier name, and also to do a policy update, so as to + // cover that bug scenario. + securityTier := api.NewTier() + securityTier.Name = "security" + order := float64(10.0) + securityTier.Spec = api.TierSpec{ + Order: &order, + } + _, err := client.Tiers().Create(utils.Ctx, securityTier, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + // Create a policy selecting felix[0] that allows egress. policy := api.NewGlobalNetworkPolicy() - policy.Name = "f0-egress" + policy.Name = "security.f0-egress" + policy.Spec.Tier = "security" policy.Spec.Egress = []api.Rule{{Action: api.Allow}} policy.Spec.Selector = fmt.Sprintf("hostname == '%s'", tc.Felixes[0].Hostname) - _, err := client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions) + _, err = client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions) Expect(err).NotTo(HaveOccurred()) // But no policy allowing ingress into felix[1]. cc.ExpectNone(tc.Felixes[0], hostW[1]) - // No policy allowing egress from felixes[1] nor ingress into - // felixes[0] + // No policy allowing egress from containers.Felix[1] nor ingress into + // containers.Felix[0] cc.ExpectNone(tc.Felixes[1], w[0]) cc.ExpectNone(tc.Felixes[1], hostW[0]) @@ -335,13 +350,14 @@ func describeHostEndpointTests(getInfra infrastructure.InfraFactory, allInterfac // Now add a policy selecting felix[1] that allows ingress. policy = api.NewGlobalNetworkPolicy() - policy.Name = "f1-ingress" + policy.Name = "security.f1-ingress" + policy.Spec.Tier = "security" policy.Spec.Ingress = []api.Rule{{Action: api.Allow}} policy.Spec.Selector = fmt.Sprintf("hostname == '%s'", tc.Felixes[1].Hostname) - _, err = client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions) + policy, err = client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions) Expect(err).NotTo(HaveOccurred()) - // Now felixes[0] can reach felixes[1]. + // Now containers.Felix[0] can reach containers.Felix[1]. cc.ExpectSome(tc.Felixes[0], hostW[1]) // But not traffic the other way. @@ -360,6 +376,16 @@ func describeHostEndpointTests(getInfra infrastructure.InfraFactory, allInterfac By("Allowing raw IP from felix[0] -> felix[1]") cc253.Expect(connectivity.Some, tc.Felixes[0], rawIPHostW253[1]) cc253.CheckConnectivity() + + // Change the f1-ingress policy to Deny. + policy.Spec.Ingress = []api.Rule{{Action: api.Deny}} + _, err = client.GlobalNetworkPolicies().Update(utils.Ctx, policy, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // Now containers.Felix[0] should NOT be able to reach containers.Felix[1]. + cc.ResetExpectations() + cc.ExpectNone(tc.Felixes[0], hostW[1]) + cc.CheckConnectivity() }) It("should allow raw IP with the right protocol only", func() { diff --git a/felix/fv/infrastructure/datastore_describe.go b/felix/fv/infrastructure/datastore_describe.go index 500d35c79cf..d762be6d428 100644 --- a/felix/fv/infrastructure/datastore_describe.go +++ b/felix/fv/infrastructure/datastore_describe.go @@ -15,10 +15,14 @@ package infrastructure import ( "fmt" + "os" + "strings" . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" + "github.com/projectcalico/calico/libcalico-go/lib/set" ) type InfraFactory func(...CreateOption) DatastoreInfra @@ -32,21 +36,52 @@ type InfraFactory func(...CreateOption) DatastoreInfra // The *datastores* parameter is a slice of the DatastoreTypes to test. func DatastoreDescribe(description string, datastores []apiconfig.DatastoreType, body func(InfraFactory)) bool { for _, ds := range datastores { - switch ds { - case apiconfig.EtcdV3: - Describe(fmt.Sprintf("%s (etcdv3 backend)", description), - func() { - body(createEtcdDatastoreInfra) - }) - case apiconfig.Kubernetes: - Describe(fmt.Sprintf("%s (kubernetes backend)", description), - func() { - body(createK8sDatastoreInfra) + + Describe(fmt.Sprintf("%s (%s backend)", description, ds), func() { + var coreFilesAtStart set.Set[string] + BeforeEach(func() { + coreFilesAtStart = readCoreFiles() + }) + + switch ds { + case apiconfig.EtcdV3: + body(createEtcdDatastoreInfra) + case apiconfig.Kubernetes: + body(createK8sDatastoreInfra) + default: + panic(fmt.Errorf("Unknown DatastoreType, %s", ds)) + } + + AfterEach(func() { + afterCoreFiles := readCoreFiles() + coreFilesAtStart.Iter(func(item string) error { + afterCoreFiles.Discard(item) + return nil }) - default: - panic(fmt.Errorf("Unknown DatastoreType, %s", ds)) - } + if afterCoreFiles.Len() != 0 { + if CurrentGinkgoTestDescription().Failed { + Fail(fmt.Sprintf("Test FAILED and new core files were detected during tear-down: %v. "+ + "Felix must have panicked during the test.", afterCoreFiles.Slice())) + return + } + Fail(fmt.Sprintf("Test PASSED but new core files were detected during tear-down: %v. "+ + "Felix must have panicked during the test.", afterCoreFiles.Slice())) + } + }) + }) } return true } + +func readCoreFiles() set.Set[string] { + tmpFiles, err := os.ReadDir("/tmp") + Expect(err).NotTo(HaveOccurred()) + var coreFiles []string + for _, f := range tmpFiles { + if strings.HasPrefix(f.Name(), "core_felix-") { + coreFiles = append(coreFiles, f.Name()) + } + } + return set.From(coreFiles...) +} diff --git a/felix/fv/infrastructure/felix.go b/felix/fv/infrastructure/felix.go index 64d47789d85..e2ffb434d9b 100644 --- a/felix/fv/infrastructure/felix.go +++ b/felix/fv/infrastructure/felix.go @@ -16,6 +16,7 @@ package infrastructure import ( "bufio" + "context" "fmt" "os" "path" @@ -26,8 +27,13 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" log "github.com/sirupsen/logrus" + client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/options" + "github.com/projectcalico/calico/felix/bpf/jump" "github.com/projectcalico/calico/felix/bpf/polprog" "github.com/projectcalico/calico/felix/fv/containers" @@ -119,9 +125,7 @@ func RunFelix(infra DatastoreInfra, id int, options TopologyOptions) *Felix { // are called concurrently with other instances of RunFelix so it's important to only // read from options.*. envVars := map[string]string{ - // Enable core dumps. - "GOTRACEBACK": "crash", - "GORACE": "history_size=2", + "GORACE": "history_size=2", // Tell the wrapper to set the core file name pattern so we can find the dump. "SET_CORE_PATTERN": "true", @@ -135,6 +139,9 @@ func RunFelix(infra DatastoreInfra, id int, options TopologyOptions) *Felix { // Disable log dropping, because it can cause flakes in tests that look for particular logs. "FELIX_DEBUGDISABLELOGDROPPING": "true", } + if options.FelixCoreDumpsEnabled { + envVars["FELIX_GOTRACEBACK"] = "crash" + } // Collect the volumes for this container. wd, err := os.Getwd() Expect(err).NotTo(HaveOccurred(), "failed to get working directory") @@ -262,6 +269,12 @@ func (f *Felix) Stop() { _ = f.ExecMayFail("rmdir", path.Join("/run/calico/cgroup/", f.Name)) } f.Container.Stop() + + if CurrentGinkgoTestDescription().Failed { + Expect(f.DataRaces()).To(BeEmpty(), "Test FAILED and data races were detected in the logs at teardown.") + } else { + Expect(f.DataRaces()).To(BeEmpty(), "Test PASSED but data races were detected in the logs at teardown.") + } } func (f *Felix) Restart() { @@ -567,3 +580,21 @@ func (p PrometheusMetric) Float() (float64, error) { } return strconv.ParseFloat(raw, 64) } + +func UpdateFelixConfiguration(client client.Interface, deltaFn func(*api.FelixConfiguration)) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + cfg, err := client.FelixConfigurations().Get(ctx, "default", options.GetOptions{}) + if _, doesNotExist := err.(errors.ErrorResourceDoesNotExist); doesNotExist { + cfg = api.NewFelixConfiguration() + cfg.Name = "default" + deltaFn(cfg) + _, err = client.FelixConfigurations().Create(ctx, cfg, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) + } else { + Expect(err).NotTo(HaveOccurred()) + deltaFn(cfg) + _, err = client.FelixConfigurations().Update(ctx, cfg, options.SetOptions{}) + Expect(err).NotTo(HaveOccurred()) + } +} diff --git a/felix/fv/infrastructure/infra_k8s.go b/felix/fv/infrastructure/infra_k8s.go index 88ba16a1f03..50108ec3cce 100644 --- a/felix/fv/infrastructure/infra_k8s.go +++ b/felix/fv/infrastructure/infra_k8s.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -150,7 +150,11 @@ func TearDownK8sInfra(kds *K8sDatastoreInfra) { } func createK8sDatastoreInfra(opts ...CreateOption) DatastoreInfra { - infra, err := GetK8sDatastoreInfra(K8SInfraLocalCluster, opts...) + return createK8sDatastoreInfraWithIndex(K8SInfraLocalCluster, opts...) +} + +func createK8sDatastoreInfraWithIndex(index K8sInfraIndex, opts ...CreateOption) DatastoreInfra { + infra, err := GetK8sDatastoreInfra(index, opts...) Expect(err).NotTo(HaveOccurred()) return infra } @@ -194,7 +198,7 @@ func (kds *K8sDatastoreInfra) PerTestSetup(index K8sInfraIndex) { // In BPF mode, start BPF logging. arch := utils.GetSysArch() - if os.Getenv("FELIX_FV_ENABLE_BPF") == "true" { + if os.Getenv("FELIX_FV_ENABLE_BPF") == "true" && index == K8SInfraLocalCluster { kds.bpfLog = containers.Run("bpf-log", containers.RunOpts{ AutoRemove: true, @@ -211,6 +215,9 @@ func (kds *K8sDatastoreInfra) runK8sApiserver() { utils.Config.K8sImage, "kube-apiserver", "--v=0", + // NOTE! We must disable UnauthenticatedHTTP2DOSMitigation in our FV's. + // Felix uses the anonymous user for API requests in the FVs, which triggers the above feature and leads to very slow networking, and test timeouts. + "--feature-gates=UnauthenticatedHTTP2DOSMitigation=false", "--service-cluster-ip-range=" + kds.serviceClusterIPRange, "--authorization-mode=RBAC", fmt.Sprintf("--etcd-servers=http://%s:2379", kds.containerGetIPForURL(kds.etcdContainer)), @@ -557,7 +564,9 @@ func (kds *K8sDatastoreInfra) CleanUp() { cleanupIPAM, cleanupAllGlobalNetworkPolicies, cleanupAllNetworkPolicies, + cleanupAllTiers, cleanupAllHostEndpoints, + cleanupAllNetworkSets, cleanupAllFelixConfigurations, cleanupAllServices, } @@ -597,6 +606,7 @@ func (kds *K8sDatastoreInfra) GetDockerArgs() []string { "-e", "FELIX_DATASTORETYPE=kubernetes", "-e", "TYPHA_DATASTORETYPE=kubernetes", "-e", "K8S_API_ENDPOINT=" + kds.Endpoint, + "-e", "KUBERNETES_MASTER=" + kds.Endpoint, "-e", "K8S_INSECURE_SKIP_TLS_VERIFY=true", "-v", kds.CertFileName + ":/tmp/apiserver.crt", } @@ -1070,6 +1080,44 @@ func cleanupAllNetworkPolicies(clientset *kubernetes.Clientset, client client.In log.Info("Cleaned up network policies") } +func cleanupAllTiers(clientset *kubernetes.Clientset, client client.Interface) { + log.Info("Cleaning up Tiers") + ctx := context.Background() + tiers, err := client.Tiers().List(ctx, options.ListOptions{}) + if err != nil { + log.WithError(err).Panicf("failed to list tiers") + } + log.WithField("count", len(tiers.Items)).Info("Tiers present") + for _, tier := range tiers.Items { + if tier.Name == names.DefaultTierName || tier.Name == names.AdminNetworkPolicyTierName { + continue + } + + _, err = client.Tiers().Delete(ctx, tier.Name, options.DeleteOptions{}) + if err != nil { + log.WithError(err).Panicf("failed to delete tier %s", tier.Name) + } + } + log.Info("Cleaned up Tiers") +} + +func cleanupAllNetworkSets(clientset *kubernetes.Clientset, client client.Interface) { + log.Info("Cleaning up network sets") + ctx := context.Background() + ns, err := client.NetworkSets().List(ctx, options.ListOptions{}) + if err != nil { + panic(err) + } + log.WithField("count", len(ns.Items)).Info("networksets present") + for _, n := range ns.Items { + _, err = client.HostEndpoints().Delete(ctx, n.Name, options.DeleteOptions{}) + if err != nil { + panic(err) + } + } + log.Info("Cleaned up host networksets") +} + func cleanupAllHostEndpoints(clientset *kubernetes.Clientset, client client.Interface) { log.Info("Cleaning up host endpoints") ctx := context.Background() diff --git a/felix/fv/infrastructure/topology.go b/felix/fv/infrastructure/topology.go index 9e3cc197c84..9e512d91b4d 100644 --- a/felix/fv/infrastructure/topology.go +++ b/felix/fv/infrastructure/topology.go @@ -41,6 +41,7 @@ import ( type TopologyOptions struct { FelixLogSeverity string FelixDebugFilenameRegex string + FelixCoreDumpsEnabled bool EnableIPv6 bool // Temporary flag to implement and test IPv6 in bpf dataplane. // TODO: Remove it when IPv6 implementation in BPF mode is complete. @@ -97,19 +98,20 @@ func DefaultTopologyOptions() TopologyOptions { felixLogLevel = envLogLevel } return TopologyOptions{ - FelixLogSeverity: felixLogLevel, - EnableIPv6: os.Getenv("FELIX_FV_ENABLE_BPF") != "true", - BPFEnableIPv6: false, - ExtraEnvVars: map[string]string{}, - ExtraVolumes: map[string]string{}, - WithTypha: false, - WithFelixTyphaTLS: false, - TyphaLogSeverity: "info", - IPIPEnabled: true, - IPIPRoutesEnabled: true, - IPPoolCIDR: DefaultIPPoolCIDR, - IPv6PoolCIDR: DefaultIPv6PoolCIDR, - UseIPPools: true, + FelixLogSeverity: felixLogLevel, + FelixCoreDumpsEnabled: true, + EnableIPv6: os.Getenv("FELIX_FV_ENABLE_BPF") != "true", + BPFEnableIPv6: false, + ExtraEnvVars: map[string]string{}, + ExtraVolumes: map[string]string{}, + WithTypha: false, + WithFelixTyphaTLS: false, + TyphaLogSeverity: "info", + IPIPEnabled: true, + IPIPRoutesEnabled: true, + IPPoolCIDR: DefaultIPPoolCIDR, + IPv6PoolCIDR: DefaultIPv6PoolCIDR, + UseIPPools: true, } } @@ -120,7 +122,12 @@ const ( DefaultIPv6PoolCIDR = "dead:beef::/64" ) -func CreateDefaultIPPoolFromOpts(ctx context.Context, client client.Interface, opts TopologyOptions, ipVersion int) (*api.IPPool, error) { +func CreateDefaultIPPoolFromOpts( + ctx context.Context, + client client.Interface, + opts TopologyOptions, + ipVersion int, +) (*api.IPPool, error) { ipPool := api.NewIPPool() switch ipVersion { @@ -169,7 +176,10 @@ func StartSingleNodeEtcdTopology(options TopologyOptions) (tc TopologyContainers // - Configures routes between the hosts, giving each host 10.65.x.0/24, where x is the // index in the returned array. When creating workloads, use IPs from the relevant block. // - Configures the Tunnel IP for each host as 10.65.x.1. -func StartNNodeEtcdTopology(n int, opts TopologyOptions) (tc TopologyContainers, etcd *containers.Container, client client.Interface, infra DatastoreInfra) { +func StartNNodeEtcdTopology( + n int, + opts TopologyOptions, +) (tc TopologyContainers, etcd *containers.Container, client client.Interface, infra DatastoreInfra) { log.Infof("Starting a %d-node etcd topology.", n) eds, err := GetEtcdDatastoreInfra() @@ -184,7 +194,10 @@ func StartNNodeEtcdTopology(n int, opts TopologyOptions) (tc TopologyContainers, // StartSingleNodeTopology starts an etcd container and a single Felix container; it initialises // the datastore and installs a Node resource for the Felix node. -func StartSingleNodeTopology(options TopologyOptions, infra DatastoreInfra) (tc TopologyContainers, calicoClient client.Interface) { +func StartSingleNodeTopology( + options TopologyOptions, + infra DatastoreInfra, +) (tc TopologyContainers, calicoClient client.Interface) { tc, calicoClient = StartNNodeTopology(1, options, infra) return } @@ -197,7 +210,11 @@ func StartSingleNodeTopology(options TopologyOptions, infra DatastoreInfra) (tc // - Configures routes between the hosts, giving each host 10.65.x.0/24, where x is the // index in the returned array. When creating workloads, use IPs from the relevant block. // - Configures the Tunnel IP for each host as 10.65.x.1. -func StartNNodeTopology(n int, opts TopologyOptions, infra DatastoreInfra) (tc TopologyContainers, client client.Interface) { +func StartNNodeTopology( + n int, + opts TopologyOptions, + infra DatastoreInfra, +) (tc TopologyContainers, client client.Interface) { log.WithField("options", opts).Infof("Starting a %d-node topology", n) success := false var err error diff --git a/felix/fv/ipip_test.go b/felix/fv/ipip_test.go index 8b33e26e2fc..ca68bbbb1b5 100644 --- a/felix/fv/ipip_test.go +++ b/felix/fv/ipip_test.go @@ -22,16 +22,18 @@ import ( "fmt" "os" "strings" + "syscall" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/vishvananda/netlink" + "github.com/projectcalico/calico/felix/fv/connectivity" "github.com/projectcalico/calico/felix/fv/utils" log "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/api/pkg/lib/numorstring" @@ -46,6 +48,7 @@ import ( "github.com/projectcalico/calico/felix/fv/containers" "github.com/projectcalico/calico/felix/fv/infrastructure" "github.com/projectcalico/calico/felix/fv/workload" + "github.com/projectcalico/calico/libcalico-go/lib/netlinkutils" ) var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ IPIP topology before adding host IPs to IP sets", []apiconfig.DatastoreType{apiconfig.EtcdV3, apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) { @@ -72,7 +75,11 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ IPIP topology before adding // Wait until the tunl0 device appears; it is created when felix inserts the ipip module // into the kernel. Eventually(func() error { - links, err := netlink.LinkList() + nlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) + if err != nil { + return err + } + links, err := netlinkutils.LinkListRetryEINTR(nlHandle) if err != nil { return err } diff --git a/felix/fv/policysync_test.go b/felix/fv/policysync_test.go index 92660276079..2352a566919 100644 --- a/felix/fv/policysync_test.go +++ b/felix/fv/policysync_test.go @@ -1,6 +1,6 @@ //go:build fvtests -// Copyright (c) 2019-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,29 +30,31 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" log "github.com/sirupsen/logrus" + "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - - "github.com/projectcalico/calico/libcalico-go/lib/selector" - - "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" - "github.com/projectcalico/calico/libcalico-go/lib/options" - "github.com/projectcalico/calico/pod2daemon/binder" - - "github.com/projectcalico/calico/felix/dataplane/mock" - "github.com/projectcalico/calico/libcalico-go/lib/set" - - "github.com/projectcalico/calico/felix/proto" + "google.golang.org/grpc/resolver" api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/felix/dataplane/mock" "github.com/projectcalico/calico/felix/fv/containers" "github.com/projectcalico/calico/felix/fv/infrastructure" "github.com/projectcalico/calico/felix/fv/utils" "github.com/projectcalico/calico/felix/fv/workload" + "github.com/projectcalico/calico/felix/proto" + "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/options" + "github.com/projectcalico/calico/libcalico-go/lib/selector" + "github.com/projectcalico/calico/libcalico-go/lib/set" + "github.com/projectcalico/calico/pod2daemon/binder" ) +func init() { + resolver.SetDefaultScheme("passthrough") +} + var _ = Context("_POL-SYNC_ _BPF-SAFE_ policy sync API tests", func() { var ( @@ -214,7 +216,7 @@ var _ = Context("_POL-SYNC_ _BPF-SAFE_ policy sync API tests", func() { opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) opts = append(opts, grpc.WithDialer(unixDialer)) var conn *grpc.ClientConn - conn, err = grpc.Dial(hostWlSocketPath[i], opts...) + conn, err = grpc.NewClient(hostWlSocketPath[i], opts...) Expect(err).NotTo(HaveOccurred()) wlClient := proto.NewPolicySyncClient(conn) return conn, wlClient diff --git a/felix/fv/routes_test.go b/felix/fv/routes_test.go index eaf21a36f51..9d10227f2e1 100644 --- a/felix/fv/routes_test.go +++ b/felix/fv/routes_test.go @@ -17,11 +17,16 @@ package fv_test import ( + "context" "fmt" + "regexp" "strings" + "sync" + "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/sirupsen/logrus" api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" @@ -78,6 +83,86 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ routing table tests", []api infra.Stop() }) + Describe("with a workload", func() { + BeforeEach(func() { + w[0][0] = workload.Run(tc.Felixes[0], + fmt.Sprintf("w%d", 0), + "default", + "10.65.0.2", + "8088", + "tcp", + ) + w[0][0].ConfigureInInfra(infra) + }) + + It("should handle interface rename flaps", func() { + if !BPFMode() { + // This passes locally but, in Semaphore, it hits EBUSY in iptables mode + // every time. Since we're testing routing, not our ability to rename + // an interface(!) let's rely on the BPF-mode test only. + Skip("Renaming interfaces regularly hits EBUSY in iptables mode") + } + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(1) + + errorSeenC := tc.Felixes[0].WatchStdoutFor(regexp.MustCompile(`(ERROR|WARN).*felix/route_table.go`)) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + defer wg.Done() + for ctx.Err() == nil { + logrus.Debug("Flapping interface") + w[0][0].RenameInterface(w[0][0].InterfaceName, "somename") + time.Sleep(1 * time.Millisecond) + _ = tc.Felixes[0].ExecMayFail("ip", "r", "del", w[0][0].IP) + logrus.Debug("Un-flapping interface") + w[0][0].RenameInterface("somename", w[0][0].InterfaceName) + time.Sleep(1 * time.Millisecond) + } + }() + + Consistently(errorSeenC, "20s").ShouldNot(BeClosed(), + "Expected no errors from route_table.go during interface rename flaps") + cancel() + + cc.Expect(connectivity.Some, tc.Felixes[0], w[0][0]) + cc.CheckConnectivity() + }) + + It("should handle up/down flaps", func() { + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(1) + + errorSeenC := tc.Felixes[0].WatchStdoutFor(regexp.MustCompile(`(ERROR|WARN).*felix/route_table.go`)) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + defer wg.Done() + for ctx.Err() == nil { + logrus.Debug("Flapping interface") + tc.Felixes[0].Exec("ip", "link", "set", "dev", w[0][0].InterfaceName, "down") + time.Sleep(10 * time.Millisecond) + logrus.Debug("Un-flapping interface") + tc.Felixes[0].Exec("ip", "link", "set", "dev", w[0][0].InterfaceName, "up") + time.Sleep(100 * time.Millisecond) + } + }() + + Consistently(errorSeenC, "20s").ShouldNot(BeClosed(), + "Expected no errors from route_table.go during interface up/down flaps") + cancel() + + cc.Expect(connectivity.Some, tc.Felixes[0], w[0][0]) + cc.CheckConnectivity() + }) + }) + Describe("with locally conflicting IPs", func() { BeforeEach(func() { // Start two local workloads with the same IP >:) @@ -122,6 +207,24 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ routing table tests", []api ContainSubstring(w[0][winner].InterfaceName), ) }) + + It("should resolve when winning interface goes down", func() { + // Winner is non-deterministic. + winner, loser := waitForInitialRouteProgramming() + w[0][winner].SetInterfaceUp(false) + Eventually(tc.Felixes[0].ExecOutputFn("ip", "r", "get", "10.65.0.2"), "10s").Should( + ContainSubstring(w[0][loser].InterfaceName), + ) + }) + + It("should resolve when losing interface goes down", func() { + // Winner is non-deterministic. + winner, loser := waitForInitialRouteProgramming() + w[0][loser].SetInterfaceUp(false) + Consistently(tc.Felixes[0].ExecOutputFn("ip", "r", "get", "10.65.0.2"), "5s").Should( + ContainSubstring(w[0][winner].InterfaceName), + ) + }) }) Describe("with local/remote conflicting IPs", func() { diff --git a/felix/fv/service_policy_test.go b/felix/fv/service_policy_test.go index af931db419c..11a35a4c1bb 100644 --- a/felix/fv/service_policy_test.go +++ b/felix/fv/service_policy_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -535,4 +535,98 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ Service network policy test cc.ExpectSome(w[1], w[0].Port(81)) cc.CheckConnectivity() }) + + It("should work properly in the non-default tier", func() { + // Expect basic connectivity to work. + cc.ExpectSome(w[0], w[1].Port(80)) + cc.ExpectSome(w[0], w[1].Port(81)) + cc.ExpectSome(w[1], w[0].Port(80)) + cc.ExpectSome(w[1], w[0].Port(81)) + cc.CheckConnectivity() + + // Create a default-deny egress policy in the default tier. + defaultDenyPolicy := api.NewNetworkPolicy() + defaultDenyPolicy.Namespace = "default" + defaultDenyPolicy.Name = "default-deny" + thousand := 1000.0 + defaultDenyPolicy.Spec.Tier = "default" + defaultDenyPolicy.Spec.Order = &thousand + defaultDenyPolicy.Spec.Selector = "all()" + defaultDenyPolicy.Spec.Types = []api.PolicyType{api.PolicyTypeEgress} + _, err := client.NetworkPolicies().Create(utils.Ctx, defaultDenyPolicy, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // Expect no traffic allowed. + cc.ResetExpectations() + cc.ExpectNone(w[0], w[1].Port(80)) + cc.ExpectNone(w[1], w[0].Port(80)) + cc.ExpectNone(w[0], w[1].Port(81)) + cc.ExpectNone(w[1], w[0].Port(81)) + cc.CheckConnectivity() + + // Create a Kubernetes EndpointSlice for a service named "w1-service" that includes + // the endpoint information for w1. + // + // A service isn't required, as Felix is driven entirely off of endpoint slices. + kc := infra.(*infrastructure.K8sDatastoreInfra).K8sClient + eighty := int32(80) + tcp := v1.ProtocolTCP + eps := &discovery.EndpointSlice{} + eps.Name = "w1-eps" + eps.Namespace = "default" + eps.Labels = map[string]string{"kubernetes.io/service-name": "w1-service"} + eps.AddressType = discovery.AddressTypeIPv4 + eps.Endpoints = []discovery.Endpoint{ + {Addresses: []string{w[1].IP}}, + } + eps.Ports = []discovery.EndpointPort{ + {Port: &eighty, Protocol: &tcp}, + } + eps, err = kc.DiscoveryV1().EndpointSlices("default").Create(utils.Ctx, eps, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + // Make sure we clean up after ourselves. + defer func() { + err = kc.DiscoveryV1().EndpointSlices("default").Delete(utils.Ctx, eps.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + }() + + // Create a new tier. + order := 100.0 + tier := api.NewTier() + tier.Name = "tier1" + tier.Spec.Order = &order + _, err = client.Tiers().Create(utils.Ctx, tier, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // Create a network policy which allows to the service in a new tier. + allowServicePolicy := api.NewNetworkPolicy() + allowServicePolicy.Namespace = "default" + allowServicePolicy.Name = "tier1.allow-to-w1" + allowServicePolicy.Spec.Order = &thousand + allowServicePolicy.Spec.Tier = "tier1" + allowServicePolicy.Spec.Selector = "all()" + allowServicePolicy.Spec.Types = []api.PolicyType{api.PolicyTypeEgress} + allowServicePolicy.Spec.Egress = []api.Rule{ + { + Action: api.Allow, + Destination: api.EntityRule{Services: &api.ServiceMatch{Name: "w1-service", Namespace: "default"}}, + }, + { + Action: api.Pass, + }, + } + _, err = client.NetworkPolicies().Create(utils.Ctx, allowServicePolicy, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // Expect traffic is allowed to the endpoint specified in the service - w1, TCP 80 + // Traffic the other direction, and to other ports should not be allowed. + cc.ResetExpectations() + cc.ExpectSome(w[0], w[1].Port(80)) + cc.ExpectNone(w[0], w[1].Port(81)) + cc.ExpectNone(w[1], w[0].Port(80)) + cc.ExpectNone(w[1], w[0].Port(81)) + cc.CheckConnectivity() + }) + }) diff --git a/felix/fv/test-workload/test-workload.go b/felix/fv/test-workload/test-workload.go index a7b31927b61..d09640e9640 100644 --- a/felix/fv/test-workload/test-workload.go +++ b/felix/fv/test-workload/test-workload.go @@ -20,22 +20,26 @@ import ( "fmt" "io" "net" - "os" "os/exec" "strconv" "strings" + "syscall" "time" - "github.com/projectcalico/calico/felix/fv/cgroup" - "github.com/projectcalico/calico/felix/fv/connectivity" - "github.com/projectcalico/calico/felix/fv/utils" - + cniv1 "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/plugins/pkg/ns" nsutils "github.com/containernetworking/plugins/pkg/testutils" "github.com/docopt/docopt-go" "github.com/ishidawataru/sctp" log "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" + + "github.com/projectcalico/calico/cni-plugin/pkg/dataplane/linux" + "github.com/projectcalico/calico/cni-plugin/pkg/types" + "github.com/projectcalico/calico/felix/fv/cgroup" + "github.com/projectcalico/calico/felix/fv/connectivity" + "github.com/projectcalico/calico/felix/fv/utils" + "github.com/projectcalico/calico/libcalico-go/lib/logutils" ) const usage = `test-workload, test workload for Felix FV testing. @@ -43,11 +47,12 @@ const usage = `test-workload, test workload for Felix FV testing. If is "", the workload will start in the current namespace. Usage: - test-workload [--protocol=] [--namespace-path=] [--sidecar-iptables] [--up-lo] [--mtu=] [--listen-any-ip] + test-workload [--protocol=] [--namespace-path=] [--sidecar-iptables] [--mtu=] [--listen-any-ip] ` func main() { log.SetLevel(log.DebugLevel) + logutils.ConfigureFormatter("test-workload") // If we've been told to, move into this felix's cgroup. cgroup.MaybeMoveToFelixCgroupv2() @@ -66,7 +71,6 @@ func main() { nsPath = arg.(string) } sidecarIptables := arguments["--sidecar-iptables"].(bool) - upLo := arguments["--up-lo"].(bool) mtu := 1450 if arg, ok := arguments["--mtu"]; ok && arg != nil { mtu, err = strconv.Atoi(arg.(string)) @@ -112,179 +116,71 @@ func main() { log.WithError(err).Panic("Giving up after multiple retries") } } - log.WithField("namespace", namespace).Debug("Created namespace") + log.WithField("namespace", namespace.Path()).Debug("Created namespace") - peerName := "w" + interfaceName - if len(peerName) > 11 { - peerName = peerName[:11] + conf := types.NetConf{ + MTU: mtu, + NumQueues: 1, } - // Create a veth pair. - la := netlink.NewLinkAttrs() - la.Name = interfaceName - la.MTU = mtu - veth := &netlink.Veth{ - LinkAttrs: la, - PeerName: peerName, + dp := linux.NewLinuxDataplane(conf, log.WithField("ns", namespace.Path())) + hostVethName := interfaceName + var addrs []*cniv1.IPConfig + if ipv4Addr != "" { + addrs = append(addrs, &cniv1.IPConfig{ + Address: net.IPNet{ + IP: net.ParseIP(ipv4Addr), + Mask: net.CIDRMask(32, 32), + }, + }) } - err = netlink.LinkAdd(veth) - panicIfError(err) - log.WithField("veth", veth).Debug("Created veth pair") - - err := netlink.LinkSetUp(veth) - panicIfError(err) - - peerVeth, err := netlink.LinkByName(veth.PeerName) - panicIfError(err) - - // Need to set the peer up in order to get an IPv6 address. - err = netlink.LinkSetUp(peerVeth) - panicIfError(err) - - var hostIPv6Addr net.IP - if ipv6Addr != "" { - attempts := 0 - for { - // No need to add a dummy next hop route as the host veth device will already have an IPv6 - // link local address that can be used as a next hop. - // Just fetch the address of the host end of the veth and use it as the next hop. - addresses, err := netlink.AddrList(veth, netlink.FAMILY_V6) - if err != nil { - log.WithError(err).Panic("Error listing IPv6 addresses for the host side of the veth pair") - } - - if len(addresses) < 1 { - attempts++ - if attempts > 30 { - log.WithError(err).Panic("Giving up waiting for IPv6 addresses after multiple retries") - } - - time.Sleep(100 * time.Millisecond) - continue - } - - hostIPv6Addr = addresses[0].IP - break - } + addrs = append(addrs, &cniv1.IPConfig{ + Address: net.IPNet{ + IP: net.ParseIP(ipv6Addr), + Mask: net.CIDRMask(128, 128), + }, + }) } - - // Move the workload end of the pair into the namespace, and set it up. - workloadIf, err := netlink.LinkByName(veth.PeerName) - log.WithField("workloadIf", workloadIf).Debug("Workload end") + _, v4Default, err := net.ParseCIDR("0.0.0.0/0") panicIfError(err) - err = netlink.LinkSetNsFd(workloadIf, int(namespace.Fd())) + _, v6Default, err := net.ParseCIDR("::/0") panicIfError(err) - err = namespace.Do(func(_ ns.NetNS) (err error) { - err = utils.RunCommand("ip", "link", "set", veth.PeerName, "name", "eth0") - if err != nil { - return - } - err = utils.RunCommand("ip", "link", "set", "eth0", "up") - if err != nil { - return - } - - err = utils.RunCommand("ip", "link", "set", "dev", "lo", "up") - if err != nil { - log.WithError(err).Info("Failed to set dev lo up") - } - - if ipv6Addr != "" { - // Make sure ipv6 is enabled in the container/pod network namespace. - // Without these sysctls enabled, interfaces will come up but they won't get a link local IPv6 address, - // which is required to add the default IPv6 route. - if err = writeProcSys("/proc/sys/net/ipv6/conf/all/disable_ipv6", "0"); err != nil { - log.WithError(err).Error("Failed to enable IPv6.") - return - } - - if err = writeProcSys("/proc/sys/net/ipv6/conf/default/disable_ipv6", "0"); err != nil { - log.WithError(err).Error("Failed to enable IPv6 by default.") - return - } - - if err = writeProcSys("/proc/sys/net/ipv6/conf/lo/disable_ipv6", "0"); err != nil { - log.WithError(err).Error("Failed to enable IPv6 on the loopback interface.") - return - } - - err = utils.RunCommand("ip", "-6", "addr", "add", ipv6Addr+"/128", "dev", "eth0") - if err != nil { - log.WithField("ipAddress", ipv6Addr+"/128").WithError(err).Error("Failed to add IPv6 addr to eth0.") - return - } - err = utils.RunCommand("ip", "-6", "route", "add", "default", "via", hostIPv6Addr.String(), "dev", "eth0") - if err != nil { - log.WithField("hostIP", hostIPv6Addr.String()).WithError(err).Info("Failed to add IPv6 route to eth0.") - return - } - - // Output the routing table to the log for diagnostic purposes. - err = utils.RunCommand("ip", "-6", "route") - if err != nil { - log.WithError(err).Info("Failed to output IPv6 routes.") - } - err = utils.RunCommand("ip", "-6", "addr") - if err != nil { - log.WithError(err).Info("Failed to output IPv6 addresses.") - } - } - if ipv4Addr != "" { - err = utils.RunCommand("ip", "addr", "add", ipv4Addr+"/32", "dev", "eth0") - if err != nil { - log.WithField("ipAddress", ipv4Addr+"/32").WithError(err).Error("Failed to add IPv4 addr to eth0.") - return - } - err = utils.RunCommand("ip", "route", "add", "169.254.169.254/32", "dev", "eth0") - if err != nil { - log.WithField("hostIP", hostIPv6Addr.String()).WithError(err).Info("Failed to add IPv4 route to eth0.") - return - } - err = utils.RunCommand("ip", "route", "add", "default", "via", "169.254.169.254", "dev", "eth0") - if err != nil { - log.WithField("hostIP", hostIPv6Addr.String()).WithError(err).Info("Failed to add default route to eth0.") - return - } - - // Output the routing table to the log for diagnostic purposes. - err = utils.RunCommand("ip", "route") - if err != nil { - log.WithError(err).Info("Failed to output IPv4 routes.") - return - } - err = utils.RunCommand("ip", "addr") - if err != nil { - log.WithError(err).Info("Failed to output IPv4 addresses.") - return - } - } - return - }) + routes := []*net.IPNet{ + v4Default, + v6Default, // Only used if we end up adding a v6 address. + } + hostNlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) panicIfError(err) - // Set the host end up too. - hostIf, err := netlink.LinkByName(veth.LinkAttrs.Name) - log.WithField("hostIf", hostIf).Debug("Host end") - panicIfError(err) - err = netlink.LinkSetUp(hostIf) + defer hostNlHandle.Close() + _, err = dp.DoWorkloadNetnsSetUp( + hostNlHandle, + namespace.Path(), + addrs, + "eth0", + hostVethName, + routes, + nil, + ) panicIfError(err) } else { namespace, err = ns.GetCurrentNS() panicIfError(err) } - // Print out the namespace path, so that test code can pick it up and execute subsequent - // operations in the same namespace - which (in the context of this FV framework) - // effectively means _as_ this workload. - fmt.Println(namespace.Path()) - // Now listen on the specified ports in the workload namespace. err = namespace.Do(func(_ ns.NetNS) error { - if upLo { - if err := utils.RunCommand("ip", "link", "set", "lo", "up"); err != nil { - return fmt.Errorf("failed to bring loopback up: %v", err) + if interfaceName != "" { + lo, err := netlink.LinkByName("lo") + if err != nil { + return fmt.Errorf("failed to look up 'lo' inside netns: %w", err) + } + err = netlink.LinkSetUp(lo) + if err != nil { + return fmt.Errorf("failed bring 'lo' up inside netns: %w", err) } } + if sidecarIptables { if err := doSidecarIptablesSetup(); err != nil { return fmt.Errorf("failed to setup sidecar-like iptables: %v", err) @@ -307,6 +203,11 @@ func main() { } } + // Print out the namespace path, so that test code can pick it up and execute subsequent + // operations in the same namespace - which (in the context of this FV framework) + // effectively means _as_ this workload. + fmt.Println(namespace.Path()) + handleRequest := func(conn net.Conn) { log.WithFields(log.Fields{ "localAddr": conn.LocalAddr(), @@ -541,22 +442,6 @@ func panicIfError(err error) { } } -// writeProcSys takes the sysctl path and a string value to set i.e. "0" or "1" and sets the sysctl. -func writeProcSys(path, value string) error { - f, err := os.OpenFile(path, os.O_WRONLY, 0) - if err != nil { - return err - } - n, err := f.Write([]byte(value)) - if err == nil && n < len(value) { - err = io.ErrShortWrite - } - if err1 := f.Close(); err == nil { - err = err1 - } - return err -} - // doSidecarIptablesSetup generates some iptables rules to redirect a // traffic to localhost:15001. This is to simulate a sidecar. // diff --git a/felix/fv/tiered_policy_test.go b/felix/fv/tiered_policy_test.go new file mode 100644 index 00000000000..e3796ddae2d --- /dev/null +++ b/felix/fv/tiered_policy_test.go @@ -0,0 +1,348 @@ +//go:build fvtests +// +build fvtests + +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +package fv_test + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/projectcalico/calico/felix/fv/connectivity" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/felix/fv/infrastructure" + "github.com/projectcalico/calico/felix/fv/utils" + "github.com/projectcalico/calico/felix/fv/workload" + "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" + client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/options" +) + +var ( + float0_0 = float64(0.0) + float1_0 = float64(1.0) + float2_0 = float64(2.0) + float3_0 = float64(3.0) + + actionPass = api.Pass + actionDeny = api.Deny +) + +// Felix1 Felix2 +// EP1-1 <-+-------> EP2-1 +// \-------> EP2-2 +// `------> EP2-3 +// `-----> EP2-4 +// +// ^ ^-- Apply test policies here (for ingress and egress) +// `-------------- Allow all policy +// +// Egress Policies (dest ep1-1) +// Tier1 | Tier2 | Default | Profile +// np1-1 (P2-1,D2-2) | snp2-1 (A2-1) | sknp3.1 (N2-1) | (default A) +// gnp2-4 (N1-1) | gnp2-2 (D2-3) | -> sknp3.9 | +// +// Ingress Policies (source ep1-1) +// +// Tier1 | Tier2 | Default | Profile +// np1-1 (A2-1,P2-2) | sgnp2-2 (N2-3) | snp3.2 (A2-2) | (default A) +// gnp2-4 (N1-1) | snp2-3 (A2-2,D2-3) | np3.3 (A2-2) | +// | np2-4 (D2-3) | snp3.4 (A2-2) | +// +// A=allow; D=deny; P=pass; N=no-match + +// These tests include tests of Kubernetes policies as well as other policy types. To ensure we have the correct +// behavior, run using the Kubernetes infrastructure only. +var _ = infrastructure.DatastoreDescribe("connectivity tests with policy tiers _BPF-SAFE_", []apiconfig.DatastoreType{apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) { + const ( + wepPort = 8055 + svcPort = 8066 + ) + wepPortStr := fmt.Sprintf("%d", wepPort) + svcPortStr := fmt.Sprintf("%d", svcPort) + + var ( + infra infrastructure.DatastoreInfra + opts infrastructure.TopologyOptions + tc infrastructure.TopologyContainers + client client.Interface + ep1_1, ep2_1, ep2_2, ep2_3, ep2_4 *workload.Workload + cc *connectivity.Checker + ) + clusterIP := "10.101.0.10" + + BeforeEach(func() { + infra = getInfra() + opts = infrastructure.DefaultTopologyOptions() + opts.IPIPEnabled = false + + // Start felix instances. + tc, client = infrastructure.StartNNodeTopology(2, opts, infra) + + // Install a default profile that allows all ingress and egress, in the absence of any Policy. + infra.AddDefaultAllow() + + // Create workload on host 1. + ep1_1 = workload.Run(tc.Felixes[0], "ep1-1", "default", "10.65.0.0", wepPortStr, "tcp") + ep1_1.ConfigureInInfra(infra) + + ep2_1 = workload.Run(tc.Felixes[1], "ep2-1", "default", "10.65.1.0", wepPortStr, "tcp") + ep2_1.ConfigureInInfra(infra) + + ep2_2 = workload.Run(tc.Felixes[1], "ep2-2", "default", "10.65.1.1", wepPortStr, "tcp") + ep2_2.ConfigureInInfra(infra) + + ep2_3 = workload.Run(tc.Felixes[1], "ep2-3", "default", "10.65.1.2", wepPortStr, "tcp") + ep2_3.ConfigureInInfra(infra) + + ep2_4 = workload.Run(tc.Felixes[1], "ep2-4", "default", "10.65.1.3", wepPortStr, "tcp") + ep2_4.ConfigureInInfra(infra) + + // Create tiers tier1 and tier2 + tier := api.NewTier() + tier.Name = "tier1" + tier.Spec.Order = &float1_0 + _, err := client.Tiers().Create(utils.Ctx, tier, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + tier = api.NewTier() + tier.Name = "tier2" + tier.Spec.Order = &float2_0 + tier.Spec.DefaultAction = &actionDeny + _, err = client.Tiers().Create(utils.Ctx, tier, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // Allow all traffic to/from ep1-1 + gnp := api.NewGlobalNetworkPolicy() + gnp.Name = "default.ep1-1-allow-all" + gnp.Spec.Order = &float1_0 + gnp.Spec.Tier = "default" + gnp.Spec.Selector = ep1_1.NameSelector() + gnp.Spec.Types = []api.PolicyType{api.PolicyTypeIngress, api.PolicyTypeEgress} + gnp.Spec.Egress = []api.Rule{{Action: api.Allow}} + gnp.Spec.Ingress = []api.Rule{{Action: api.Allow}} + _, err = client.GlobalNetworkPolicies().Create(utils.Ctx, gnp, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // gnp2-4 egress(N1-1) ingress(N1-1) + gnp = api.NewGlobalNetworkPolicy() + gnp.Name = "tier1.ep2-4" + gnp.Spec.Order = &float1_0 + gnp.Spec.Tier = "tier1" + gnp.Spec.Selector = ep2_4.NameSelector() + gnp.Spec.Types = []api.PolicyType{api.PolicyTypeIngress, api.PolicyTypeEgress} + gnp.Spec.Ingress = []api.Rule{ + {Action: api.Allow, Source: api.EntityRule{Selector: ep2_1.NameSelector()}}, + } + gnp.Spec.Egress = []api.Rule{ + {Action: api.Allow, Destination: api.EntityRule{Selector: ep2_1.NameSelector()}}, + } + _, err = client.GlobalNetworkPolicies().Create(utils.Ctx, gnp, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // np1-1 egress: (P2-1,D2-2) ingress: (A2-1,P2-2) + np := api.NewNetworkPolicy() + np.Name = "tier1.np1-1" + np.Namespace = "default" + np.Spec.Order = &float1_0 + np.Spec.Tier = "tier1" + np.Spec.Selector = "name in {'" + ep2_1.Name + "', '" + ep2_2.Name + "'}" + np.Spec.Types = []api.PolicyType{api.PolicyTypeIngress, api.PolicyTypeEgress} + np.Spec.Egress = []api.Rule{ + {Action: api.Pass, Source: api.EntityRule{Selector: ep2_1.NameSelector()}}, + {Action: api.Deny, Source: api.EntityRule{Selector: ep2_2.NameSelector()}}, + } + np.Spec.Ingress = []api.Rule{ + {Action: api.Allow, Destination: api.EntityRule{Selector: ep2_1.NameSelector()}}, + {Action: api.Pass, Destination: api.EntityRule{Selector: ep2_2.NameSelector()}}, + } + _, err = client.NetworkPolicies().Create(utils.Ctx, np, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // gnp2-2 egress: (A2-3) + gnp = api.NewGlobalNetworkPolicy() + gnp.Name = "tier2.gnp2-2" + gnp.Spec.Order = &float2_0 + gnp.Spec.Tier = "tier2" + gnp.Spec.Selector = ep2_3.NameSelector() + gnp.Spec.Types = []api.PolicyType{api.PolicyTypeEgress} + gnp.Spec.Egress = []api.Rule{{Action: api.Deny}} + _, err = client.GlobalNetworkPolicies().Create(utils.Ctx, gnp, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // np2-4 ingress: (D2-3) + np = api.NewNetworkPolicy() + np.Name = "tier2.np2-4" + np.Namespace = "default" + np.Spec.Order = &float3_0 + np.Spec.Tier = "tier2" + np.Spec.Selector = ep2_3.NameSelector() + np.Spec.Types = []api.PolicyType{api.PolicyTypeIngress} + np.Spec.Ingress = []api.Rule{{Action: api.Deny}} + _, err = client.NetworkPolicies().Create(utils.Ctx, np, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // np3.3 ingress: (A2-2) + np = api.NewNetworkPolicy() + np.Name = "default.np3-3" + np.Namespace = "default" + np.Spec.Order = &float2_0 + np.Spec.Tier = "default" + np.Spec.Selector = ep2_2.NameSelector() + np.Spec.Types = []api.PolicyType{api.PolicyTypeIngress} + np.Spec.Ingress = []api.Rule{{Action: api.Allow}} + _, err = client.NetworkPolicies().Create(utils.Ctx, np, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + // Create a service that maps to ep2_1. Rather than checking connectivity to the endpoint we'll go via + // the service to test the destination service name handling. + svcName := "test-service" + k8sClient := infra.(*infrastructure.K8sDatastoreInfra).K8sClient + tSvc := k8sService(svcName, clusterIP, ep2_1, svcPort, wepPort, 0, "tcp") + tSvcNamespace := tSvc.ObjectMeta.Namespace + _, err = k8sClient.CoreV1().Services(tSvcNamespace).Create(context.Background(), tSvc, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + // Wait for the endpoints to be updated and for the address to be ready. + Expect(ep2_1.IP).NotTo(Equal("")) + getEpsFunc := k8sGetEpsForServiceFunc(k8sClient, tSvc) + epCorrectFn := func() error { + eps := getEpsFunc() + if len(eps) != 1 { + return fmt.Errorf("Wrong number of endpoints: %#v", eps) + } + addrs := eps[0].Addresses + if len(addrs) != 1 { + return fmt.Errorf("Wrong number of addresses: %#v", eps[0]) + } + if addrs[0].IP != ep2_1.IP { + return fmt.Errorf("Unexpected IP: %s != %s", addrs[0].IP, ep2_1.IP) + } + ports := eps[0].Ports + if len(ports) != 1 { + return fmt.Errorf("Wrong number of ports: %#v", eps[0]) + } + if ports[0].Port != int32(wepPort) { + return fmt.Errorf("Wrong port %d != svcPort", ports[0].Port) + } + return nil + } + Eventually(epCorrectFn, "10s").ShouldNot(HaveOccurred()) + + if os.Getenv("FELIX_FV_ENABLE_BPF") != "true" { + // Wait for felix to see and program some expected nflog entries, and for the cluster IP to appear. + rulesProgrammed := func() bool { + var out0, out1 string + var err error + if NFTMode() { + out0, err = tc.Felixes[0].ExecOutput("nft", "list", "table", "ip", "calico") + Expect(err).NotTo(HaveOccurred()) + out1, err = tc.Felixes[1].ExecOutput("nft", "list", "table", "ip", "calico") + Expect(err).NotTo(HaveOccurred()) + } else { + out0, err = tc.Felixes[0].ExecOutput("iptables-save", "-t", "filter") + Expect(err).NotTo(HaveOccurred()) + out1, err = tc.Felixes[1].ExecOutput("iptables-save", "-t", "filter") + Expect(err).NotTo(HaveOccurred()) + } + return strings.Count(out0, "default.ep1-1-allow-all") > 0 && + strings.Count(out1, "default.ep1-1-allow-all") == 0 + } + Eventually(rulesProgrammed, "10s", "1s").Should(BeTrue(), + "Expected iptables rules to appear on the correct felix instances") + + // Mimic the kube-proxy service iptable clusterIP rule. + for _, f := range tc.Felixes { + f.Exec("iptables", "-t", "nat", "-A", "PREROUTING", + "-p", "tcp", + "-d", clusterIP, + "-m", "tcp", "--dport", svcPortStr, + "-j", "DNAT", "--to-destination", + ep2_1.IP+":"+wepPortStr) + } + + } + }) + + createBaseConnectivityChecker := func() *connectivity.Checker { + cc = &connectivity.Checker{} + cc.ExpectSome(ep1_1, connectivity.TargetIP(clusterIP), uint16(svcPort)) // allowed by np1-1 + cc.ExpectSome(ep1_1, ep2_2) // allowed by np3-3 + cc.ExpectNone(ep1_1, ep2_3) // denied by np2-4 + + cc.ExpectSome(ep2_1, ep1_1) // allowed by profile + cc.ExpectNone(ep2_2, ep1_1) // denied by np1-1 + cc.ExpectNone(ep2_3, ep1_1) // denied by gnp2-2 + + return cc + } + + It("should test connectivity between workloads with tier with Pass default action", func() { + By("checking the initial connectivity") + cc := createBaseConnectivityChecker() + cc.ExpectNone(ep1_1, ep2_4) // denied by end of tier1 deny + cc.ExpectNone(ep2_4, ep1_1) // denied by end of tier1 deny + + // Do 3 rounds of connectivity checking. + cc.CheckConnectivity() + + By("changing the tier's default action to Pass") + tier, err := client.Tiers().Get(utils.Ctx, "tier1", options.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + tier.Spec.DefaultAction = &actionPass + _, err = client.Tiers().Update(utils.Ctx, tier, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + cc = createBaseConnectivityChecker() + cc.ExpectSome(ep1_1, ep2_4) // allowed by profile, as tier1 DefaultAction is set to Pass. + cc.ExpectSome(ep2_4, ep1_1) // allowed by profile, as tier1 DefaultAction is set to Pass. + + cc.CheckConnectivity() + + By("changing the tier's default action back to Deny") + tier, err = client.Tiers().Get(utils.Ctx, "tier1", options.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + tier.Spec.DefaultAction = &actionDeny + _, err = client.Tiers().Update(utils.Ctx, tier, utils.NoOptions) + Expect(err).NotTo(HaveOccurred()) + + cc = createBaseConnectivityChecker() + cc.ExpectNone(ep1_1, ep2_4) // denied by end of tier1 deny + cc.ExpectNone(ep2_4, ep1_1) // denied by end of tier1 deny + + cc.CheckConnectivity() + }) + + AfterEach(func() { + if CurrentGinkgoTestDescription().Failed { + for _, felix := range tc.Felixes { + felix.Exec("iptables-save", "-c") + felix.Exec("ipset", "list") + felix.Exec("ip", "r") + felix.Exec("ip", "a") + } + } + + ep1_1.Stop() + ep2_1.Stop() + ep2_2.Stop() + ep2_3.Stop() + ep2_4.Stop() + tc.Stop() + + if CurrentGinkgoTestDescription().Failed { + infra.DumpErrorData() + } + infra.Stop() + }) +}) diff --git a/felix/fv/vxlan_test.go b/felix/fv/vxlan_test.go index 2756ac7315b..a660dbcab18 100644 --- a/felix/fv/vxlan_test.go +++ b/felix/fv/vxlan_test.go @@ -878,7 +878,7 @@ func createBaseTopologyOptions(vxlanMode api.VXLANMode, enableIPv6 bool, routeSo // for these tests. Since we're testing in containers anyway, checksum offload can't really be // tested but we can verify the state with ethtool. topologyOptions.ExtraEnvVars["FELIX_FeatureDetectOverride"] = fmt.Sprintf("ChecksumOffloadBroken=%t", brokenXSum) - + topologyOptions.FelixDebugFilenameRegex = "vxlan|route_table|l3_route_resolver|int_dataplane" return topologyOptions } diff --git a/felix/fv/winfv/policy_test.go b/felix/fv/winfv/policy_test.go index 8c727a92e1d..0f166f4759d 100644 --- a/felix/fv/winfv/policy_test.go +++ b/felix/fv/winfv/policy_test.go @@ -16,9 +16,9 @@ package winfv_test import ( "bytes" - "errors" "fmt" "os/exec" + "time" "context" @@ -33,6 +33,18 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/options" ) +func Powershell(args ...string) string { + stdOut, _, err := powershell(args...) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + return stdOut +} + +func PowershellWithError(args ...string) string { + _, stdErr, err := powershell(args...) + ExpectWithOffset(1, err).To(HaveOccurred()) + return stdErr +} + func powershell(args ...string) (string, string, error) { ps, err := exec.LookPath("powershell.exe") if err != nil { @@ -58,26 +70,18 @@ func powershell(args ...string) (string, string, error) { func getPodIP(name, namespace string) string { cmd := fmt.Sprintf(`c:\k\kubectl.exe --kubeconfig=c:\k\config get pod %s -n %s -o jsonpath='{.status.podIP}'`, name, namespace) - ip, _, err := powershell(cmd) - if err != nil { - Fail(fmt.Sprintf("could not get pod IP for %v/%v: %v", namespace, name, err)) - } - return ip + return Powershell(cmd) } -func kubectlExec(command string) error { +func kubectlExec(command string) { cmd := fmt.Sprintf(`c:\k\kubectl.exe --kubeconfig=c:\k\config -n demo exec %v`, command) - stdout, stderr, err := powershell(cmd) - if err != nil { - log.WithFields(log.Fields{"stderr": stderr, "stdout": stdout}).WithError(err).Error("Error running kubectl command") - return err - } - if stderr != "" { - log.WithFields(log.Fields{"stderr": stderr, "stdout": stdout}).WithError(err).Error("kubectl stderr indicates error") - return errors.New("non-empty stderr") - } - log.WithFields(log.Fields{"stderr": stderr, "stdout": stdout}).Info("kubectl command succeeded") - return nil + _ = Powershell(cmd) +} + +func kubectlExecWithErrors(command string) { + cmd := fmt.Sprintf(`c:\k\kubectl.exe --kubeconfig=c:\k\config -n demo exec %v`, command) + err := PowershellWithError(cmd) + log.Infof("Error: %s", err) } func newClient() clientv3.Interface { @@ -86,9 +90,25 @@ func newClient() clientv3.Interface { cfg.Spec.Kubeconfig = `c:\k\config` client, err := clientv3.New(*cfg) ExpectWithOffset(1, err).NotTo(HaveOccurred()) + mustInitDatastore(client) return client } +func mustInitDatastore(client clientv3.Interface) { + Eventually(func() error { + log.Info("Initializing the datastore...") + ctx, cancelFun := context.WithTimeout(context.Background(), 10*time.Second) + defer cancelFun() + err := client.EnsureInitialized( + ctx, + "v3.0.0-test", + "felix-fv", + ) + log.WithError(err).Info("EnsureInitialized result") + return err + }).ShouldNot(HaveOccurred(), "mustInitDatastore failed") +} + // These Windows policy FV tests rely on a 2 node cluster (1 Linux and 1 Windows) provisioned using internal tooling. // The test infra setup creates some pods: // - "client" and "clientB" are busybox pods @@ -100,9 +120,7 @@ func newClient() clientv3.Interface { // - "allow-nginx": egress policy that allows the porter pod to reach the nginx pods on TCP port 80 // - "allow-client": ingress policy that allows the client pods to reach the porter pods on TCP port 80 var _ = Describe("Windows policy test", func() { - var ( - porter, client, clientB, nginx, nginxB string - ) + var porter, client, clientB, nginx, nginxB string BeforeEach(func() { // Get IPs of the pods installed by the test infra setup. @@ -123,31 +141,25 @@ var _ = Describe("Windows policy test", func() { Context("ingress policy tests", func() { It("client pod can connect to porter pod", func() { - err := kubectlExec(fmt.Sprintf(`-t client -- wget %v -T 5 -qO -`, porter)) - Expect(err).NotTo(HaveOccurred()) + kubectlExec(fmt.Sprintf(`-t client -- wget %v -T 5 -qO -`, porter)) }) It("client-b pod can't connect to porter pod", func() { - err := kubectlExec(fmt.Sprintf(`-t client-b -- wget %v -T 5 -qO -`, porter)) - Expect(err).To(HaveOccurred()) + kubectlExecWithErrors(fmt.Sprintf(`-t client-b -- wget %v -T 5 -qO -`, porter)) }) }) Context("egress policy tests", func() { It("porter pod can connect to nginx pod", func() { - err := kubectlExec(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginx)) - Expect(err).NotTo(HaveOccurred()) + kubectlExec(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginx)) }) It("porter pod cannot connect to nginx-b pod", func() { - err := kubectlExec(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginxB)) - Expect(err).To(HaveOccurred()) + kubectlExecWithErrors(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginxB)) }) It("porter pod cannot connect to google.com", func() { - err := kubectlExec(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 www.google.com'`) - Expect(err).To(HaveOccurred()) + kubectlExecWithErrors(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 www.google.com'`) }) It("porter pod can connect to nginxB after creating service egress policy", func() { // Assert nginx-b is not reachable. - err := kubectlExec(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginxB)) - Expect(err).To(HaveOccurred()) + kubectlExecWithErrors(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginxB)) // Create a policy allowing to the nginx-b service. client := newClient() @@ -166,7 +178,7 @@ var _ = Describe("Windows policy test", func() { }, }, } - _, err = client.NetworkPolicies().Create(context.Background(), &p, options.SetOptions{}) + _, err := client.NetworkPolicies().Create(context.Background(), &p, options.SetOptions{}) Expect(err).NotTo(HaveOccurred()) defer func() { _, err = client.NetworkPolicies().Delete(context.Background(), "demo", "allow-nginx-b", options.DeleteOptions{}) @@ -174,8 +186,7 @@ var _ = Describe("Windows policy test", func() { }() // Assert that it's now reachable. - err = kubectlExec(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginxB)) - Expect(err).NotTo(HaveOccurred()) + kubectlExec(fmt.Sprintf(`-t porter -- powershell -Command 'Invoke-WebRequest -UseBasicParsing -TimeoutSec 5 %v'`, nginxB)) }) }) }) diff --git a/felix/fv/workload/workload.go b/felix/fv/workload/workload.go index 1df6d9795b3..5feff8ef237 100644 --- a/felix/fv/workload/workload.go +++ b/felix/fv/workload/workload.go @@ -18,6 +18,7 @@ import ( "bufio" "fmt" "io" + "math/rand" "os" "os/exec" "regexp" @@ -26,6 +27,7 @@ import ( "sync" "time" + "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/pkg/errors" log "github.com/sirupsen/logrus" @@ -276,7 +278,7 @@ func (w *Workload) Start() error { log.WithError(err).Info("End of workload stderr") return } - log.Infof("Workload %s stderr: %s", w.Name, strings.TrimSpace(string(line))) + _, _ = fmt.Fprintf(ginkgo.GinkgoWriter, "%v[stderr] %v", w.Name, line) } }() @@ -294,6 +296,7 @@ func (w *Workload) Start() error { defer errDone.Wait() return fmt.Errorf("reading from stdout failed: %w", err) } + log.WithField("workload", w.Name).Infof("Workload namespace path: %s", namespacePath) w.namespacePath = strings.TrimSpace(namespacePath) @@ -304,7 +307,7 @@ func (w *Workload) Start() error { log.WithError(err).Info("End of workload stdout") return } - log.Infof("Workload %s stdout: %s", w.Name, strings.TrimSpace(string(line))) + _, _ = fmt.Fprintf(ginkgo.GinkgoWriter, "%v[stdout] %v", w.Name, line) } }() @@ -598,7 +601,6 @@ func startSideService(w *Workload) (*SideService, error) { } testWorkloadShArgs = append(testWorkloadShArgs, "--sidecar-iptables", - "--up-lo", fmt.Sprintf("'--namespace-path=%s'", w.namespacePath), "''", // interface name, not important "127.0.0.1", @@ -635,8 +637,10 @@ type PersistentConnectionOpts struct { Timeout time.Duration } -func (w *Workload) StartPersistentConnection(ip string, port int, - opts PersistentConnectionOpts) *connectivity.PersistentConnection { +func (w *Workload) StartPersistentConnection( + ip string, port int, + opts PersistentConnectionOpts, +) *connectivity.PersistentConnection { pc := &connectivity.PersistentConnection{ RuntimeName: w.C.Name, @@ -843,3 +847,30 @@ func (w *Workload) InterfaceIndex() int { log.Infof("%v is ifindex %v", w.InterfaceName, ifIndex) return ifIndex } + +func (w *Workload) RenameInterface(from, to string) { + var err error + sleep := 100 * time.Millisecond + for try := 0; try < 40; try++ { + // Can fail with EBUSY. + err = w.C.ExecMayFail("ip", "link", "set", from, "name", to) + if err == nil { + return + } + time.Sleep(sleep) + sleep = time.Duration(float64(sleep) * (1.5 + rand.Float64())) + const maxSleep = 2 * time.Second + if sleep > maxSleep { + sleep = maxSleep + } + } + ginkgo.Fail(fmt.Sprintf("Failed to rename interface %s to %s after several retries: %s", from, to, err)) +} + +func (w *Workload) SetInterfaceUp(b bool) { + if b { + w.C.Exec("ip", "link", "set", "up", w.InterfaceName) + } else { + w.C.Exec("ip", "link", "set", "down", w.InterfaceName) + } +} diff --git a/felix/fv/xdp_test.go b/felix/fv/xdp_test.go index 7cab2290158..d7083252020 100644 --- a/felix/fv/xdp_test.go +++ b/felix/fv/xdp_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ import ( ) const ( - resyncPeriod = 11 * time.Second + resyncPeriod = 20 * time.Second ) var ( @@ -77,6 +77,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { opts.ExtraEnvVars = map[string]string{ "FELIX_GENERICXDPENABLED": "1", "FELIX_XDPREFRESHINTERVAL": "10", + "FELIX_XDPENABLED": "true", "FELIX_LOGSEVERITYSCREEN": "debug", "FELIX_FAILSAFEINBOUNDHOSTPORTS": "tcp:22, udp:68, tcp:179, tcp:2379, tcp:2380, " + "tcp:5473, tcp:6443, tcp:6666, tcp:6667, " + proto + ":1234", // defaults + 1234 @@ -183,23 +184,6 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { expectNoConnectivity(cc) }) - xdpProgramID := func(felix *infrastructure.Felix, iface string) int { - out, err := felix.ExecCombinedOutput("ip", "link", "show", "dev", iface) - Expect(err).NotTo(HaveOccurred()) - r := regexp.MustCompile(`prog/xdp id (\d+)`) - matches := r.FindStringSubmatch(out) - if len(matches) == 0 { - return 0 - } - id, err := strconv.Atoi(matches[1]) - Expect(err).NotTo(HaveOccurred()) - return id - } - - xdpProgramAttached := func(felix *infrastructure.Felix, iface string) bool { - return xdpProgramID(felix, iface) != 0 - } - xdpProgramAttachedServerEth0 := func() bool { return xdpProgramAttached(tc.Felixes[srvr], "eth0") } @@ -246,7 +230,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { // apply XDP policy to felix[srvr] blocking felixes[clnt] by IP serverSelector := "role=='server'" xdpPolicy := api.NewGlobalNetworkPolicy() - xdpPolicy.Name = "xdp-filter" // keep name short, so it matches with the iptables chain name + xdpPolicy.Name = "xdpf" // keep name short, so it matches with the iptables chain name xdpPolicy.Spec.Order = &order xdpPolicy.Spec.DoNotTrack = true xdpPolicy.Spec.ApplyOnForward = true @@ -266,7 +250,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { AfterEach(func() { _, _ = client.GlobalNetworkPolicies().Delete(utils.Ctx, "allow-all", options.DeleteOptions{}) _, _ = client.GlobalNetworkSets().Delete(utils.Ctx, "xdpblocklist", options.DeleteOptions{}) - _, _ = client.GlobalNetworkPolicies().Delete(utils.Ctx, "xdp-filter", options.DeleteOptions{}) + _, _ = client.GlobalNetworkPolicies().Delete(utils.Ctx, "xdpf", options.DeleteOptions{}) }) It("should have consistent XDP program attached", func() { @@ -276,7 +260,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { Context("with untracked policies deleted again", func() { BeforeEach(func() { - _, _ = client.GlobalNetworkPolicies().Delete(utils.Ctx, "xdp-filter", options.DeleteOptions{}) + _, _ = client.GlobalNetworkPolicies().Delete(utils.Ctx, "xdpf", options.DeleteOptions{}) }) It("should not have XDP program attached", func() { @@ -337,7 +321,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { Expect(doHping()).To(HaveOccurred()) if !BPFMode() && !NFTMode() { - output, err := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", "cali-pi-default.xdp-filter") + output, err := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", "cali-pi-default/default.xdpf") // the only rule that refers to a cali40-prefixed ipset should // have 0 packets/bytes because the raw small packets should've been // blocked by XDP @@ -370,7 +354,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { Expect(doPing()).To(HaveOccurred()) if !BPFMode() && !NFTMode() { - output, err := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", "cali-pi-default.xdp-filter") + output, err := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", "cali-pi-default/default.xdpf") // the only rule that refers to a cali40-prefixed ipset should // have 0 packets/bytes because the icmp packets should've been // blocked by XDP @@ -390,7 +374,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { expectBlocked(cc) }) - It("should have expected no dropped packets in iptables", func() { + It("should have expected no dropped packets in iptables / nftables", func() { versionReader, err := environment.GetKernelVersionReader() Expect(err).NotTo(HaveOccurred()) @@ -405,17 +389,19 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { expectBlocked(cc) // The only rule that refers to a cali40-prefixed ipset should have 0 packets/bytes - if !BPFMode() && !NFTMode() { - Eventually(func() string { - out, _ := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", - "cali-pi-default.xdp-filter") - return out - }).Should(MatchRegexp(`(?m)^\s+0\s+0.*cali40s:`)) - } else if NFTMode() { - Eventually(func() string { - out, _ := tc.Felixes[srvr].ExecOutput("nft", "list", "chain", "ip", "calico", "raw-cali-pi-default.xdp-filter") - return out - }).Should(MatchRegexp(`packets 0 bytes 0`)) + if !BPFMode() { + if !NFTMode() { + Eventually(func() string { + out, _ := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", + "cali-pi-default/default.xdpf") + return out + }).Should(MatchRegexp(`(?m)^\s+0\s+0.*cali40s:`)) + } else { + Eventually(func() string { + out, _ := tc.Felixes[srvr].ExecOutput("nft", "list", "chain", "ip", "calico", "raw-cali-pi-default/default.xdpf") + return out + }).Should(MatchRegexp(`packets 0 bytes 0`)) + } } }) @@ -426,7 +412,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { It("should have expected connectivity after removing the policy", func() { expectBlocked(cc) - _, err := client.GlobalNetworkPolicies().Delete(utils.Ctx, "xdp-filter", options.DeleteOptions{}) + _, err := client.GlobalNetworkPolicies().Delete(utils.Ctx, "xdpf", options.DeleteOptions{}) Expect(err).NotTo(HaveOccurred()) expectAllAllowed(cc) @@ -525,7 +511,7 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { // the only rule that refers to a cali40-prefixed ipset should have 0 packets/bytes Eventually(func() string { out, _ := tc.Felixes[srvr].ExecOutput("iptables", "-t", "raw", "-v", "-n", "-L", - "cali-pi-default.xdp-filter") + "cali-pi-default/default.xdpf") return out }).Should(MatchRegexp(`(?m)^\s+0\s+0.*cali40s:`)) } @@ -537,3 +523,20 @@ func xdpTest(getInfra infrastructure.InfraFactory, proto string) { }) }) } + +func xdpProgramID(felix *infrastructure.Felix, iface string) int { + out, err := felix.ExecCombinedOutput("ip", "link", "show", "dev", iface) + Expect(err).NotTo(HaveOccurred()) + r := regexp.MustCompile(`prog/xdp id (\d+)`) + matches := r.FindStringSubmatch(out) + if len(matches) == 0 { + return 0 + } + id, err := strconv.Atoi(matches[1]) + Expect(err).NotTo(HaveOccurred()) + return id +} + +func xdpProgramAttached(felix *infrastructure.Felix, iface string) bool { + return xdpProgramID(felix, iface) != 0 +} diff --git a/felix/generictables/match_builder.go b/felix/generictables/match_builder.go index 81dfc41ab55..a7a532646bb 100644 --- a/felix/generictables/match_builder.go +++ b/felix/generictables/match_builder.go @@ -56,6 +56,7 @@ type MatchCriteria interface { IPSetNames() (ipSetNames []string) SourcePorts(ports ...uint16) MatchCriteria NotSourcePorts(ports ...uint16) MatchCriteria + DestPort(port uint16) MatchCriteria DestPorts(ports ...uint16) MatchCriteria NotDestPorts(ports ...uint16) MatchCriteria SourcePortRanges(ports []*proto.PortRange) MatchCriteria diff --git a/felix/idalloc/idalloc_suite_test.go b/felix/idalloc/idalloc_suite_test.go index 37bbd0163e9..6d376ac9e6d 100644 --- a/felix/idalloc/idalloc_suite_test.go +++ b/felix/idalloc/idalloc_suite_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,22 +15,17 @@ package idalloc_test import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "testing" + . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" - "github.com/sirupsen/logrus" + . "github.com/onsi/gomega" - "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/testutils" ) func init() { testutils.HookLogrusForGinkgo() - logrus.AddHook(&logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) } func TestCalculationGraph(t *testing.T) { diff --git a/felix/ip/ip_addr.go b/felix/ip/ip_addr.go index a82667c0b0a..0f1d8adbdc9 100644 --- a/felix/ip/ip_addr.go +++ b/felix/ip/ip_addr.go @@ -187,6 +187,9 @@ type CIDR interface { ToIPNet() net.IPNet AsBinary() string Contains(addr Addr) bool + // IsSingleAddress returns true if the CIDR represents a single address. + // I.e. a /32 for IPv4 or a /128 for IPv6. + IsSingleAddress() bool } type V4CIDR struct { @@ -244,6 +247,10 @@ func (c V4CIDR) AsBinary() string { return ipInBinary[0 : c.prefix+4] } +func (c V4CIDR) IsSingleAddress() bool { + return c.prefix == 32 +} + type V6CIDR struct { addr V6Addr prefix uint8 @@ -304,6 +311,10 @@ func (c V6CIDR) AsBinary() string { return ipInBinary[0 : c.prefix+4] } +func (c V6CIDR) IsSingleAddress() bool { + return c.prefix == 128 +} + func FromString(s string) Addr { return FromNetIP(net.ParseIP(s)) } @@ -355,7 +366,12 @@ func FromCalicoIP(ip calinet.IP) Addr { return FromNetIP(ip.IP) } +// CIDRFromIPNet converts a *net.IPNet to a CIDR; if passed nil, +// returns nil. func CIDRFromIPNet(ipNet *net.IPNet) CIDR { + if ipNet == nil { + return nil + } ones, _ := ipNet.Mask.Size() // Mask the IP before creating the CIDR so that we have it in canonical format. ip := FromNetIP(ipNet.IP.Mask(ipNet.Mask)) diff --git a/felix/ip/ip_addr_test.go b/felix/ip/ip_addr_test.go index 377ba8bfca4..fe53ea03c31 100644 --- a/felix/ip/ip_addr_test.go +++ b/felix/ip/ip_addr_test.go @@ -134,3 +134,21 @@ var _ = DescribeTable("Contains", Entry("IPv6 /112 true", "fc00:fe11::/112", "fc00:fe11::3", true), Entry("IPv6 /112 false", "fc00:fe11::/112", "fc00:fe12::3", false), ) + +var _ = DescribeTable("IsSingleAddress", + func(inputAddr string, expected bool) { + cidr := MustParseCIDROrIP(inputAddr) + Expect(cidr.IsSingleAddress()).To(Equal(expected)) + }, + Entry("0.0.0.0/0", "0.0.0.0/0", false), + Entry("0.0.0.0", "0.0.0.0", true), + Entry("10.0.0.0/8", "10.0.0.0/8", false), + Entry("10.1.2.3/32", "10.1.2.3/32", true), + Entry("10.1.2.0/31", "10.1.2.0/31", false), + + Entry("::/0", "::/0", false), + Entry("::", "::", true), + Entry("dead::/16", "dead::/16", false), + Entry("dead::beef/128", "dead::beef/128", true), + Entry("dead::beef/127", "dead::beef/127", false), +) diff --git a/felix/ip/ip_suite_test.go b/felix/ip/ip_suite_test.go index 471eb8b420d..c31a9473fae 100644 --- a/felix/ip/ip_suite_test.go +++ b/felix/ip/ip_suite_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,15 +15,12 @@ package ip_test import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "testing" + . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" - "github.com/sirupsen/logrus" + . "github.com/onsi/gomega" - "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/testutils" ) @@ -35,6 +32,4 @@ func TestIp(t *testing.T) { func init() { testutils.HookLogrusForGinkgo() - logrus.AddHook(&logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) } diff --git a/felix/ipsets/ipset_defs.go b/felix/ipsets/ipset_defs.go index 35784921b6a..2253dbd7710 100644 --- a/felix/ipsets/ipset_defs.go +++ b/felix/ipsets/ipset_defs.go @@ -133,7 +133,7 @@ func (t IPSetType) IsMemberIPV6(member string) bool { return cidr1 case IPSetTypeBitmapPort: - return strings.HasPrefix("v6,", member) + return strings.HasPrefix(member, "v6,") } log.WithField("type", string(t)).Panic("Unknown IPSetType") return false diff --git a/felix/ipsets/ipsets.go b/felix/ipsets/ipsets.go index 99a2eef6983..8085504da74 100644 --- a/felix/ipsets/ipsets.go +++ b/felix/ipsets/ipsets.go @@ -559,8 +559,10 @@ func (s *IPSets) resyncIPSet(ipSetName string) error { // Start of a Members entry, following this, there'll be one member per // line then EOF or a blank line. - // Look up to see if this is one of our IP sets. - if !s.IPVersionConfig.OwnsIPSet(ipSetName) || s.IPVersionConfig.IsTempIPSetName(ipSetName) { + // Optimisation: skip parsing temporary IP set members. + // We only need to track their metadata to make sure they + // are deleted. + if s.IPVersionConfig.IsTempIPSetName(ipSetName) { if debug { s.logCxt.WithField("name", ipSetName).Debug("Skip parsing members of IP set.") } @@ -651,6 +653,12 @@ func (s *IPSets) runIPSetList(arg string, parsingFunc func(*bufio.Scanner) error // Use a scanner to chunk the input into lines. scanner := bufio.NewScanner(out) parsingErr := parsingFunc(scanner) + if parsingErr == nil { + // In case the parsingFunc stopped early, drain stdout fully. + for scanner.Scan() { + } + parsingErr = scanner.Err() + } closeErr := out.Close() err = cmd.Wait() logCxt := s.logCxt.WithField("stderr", stderr.String()) @@ -814,6 +822,13 @@ func (s *IPSets) writeUpdates(setName string, w io.Writer) (err error) { // If the metadata needs to change then we have to write to a temporary IP // set and swap it into place. needTempIPSet := dpExists && dpMeta != desiredMeta + if needTempIPSet { + log.WithFields(log.Fields{ + "desired": desiredMeta, + "dataplane": dpMeta, + "setName": setName, + }).Info("IP set metadata change, need to use a temporary IP set.") + } // If the IP set doesn't exist yet, we need to create it. needCreate := !dpExists diff --git a/felix/ipsets/ipsets_suite_test.go b/felix/ipsets/ipsets_suite_test.go index 83f4405d273..c2bd5d46331 100644 --- a/felix/ipsets/ipsets_suite_test.go +++ b/felix/ipsets/ipsets_suite_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,22 +15,17 @@ package ipsets_test import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "testing" + . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" - "github.com/sirupsen/logrus" + . "github.com/onsi/gomega" - "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/testutils" ) func init() { testutils.HookLogrusForGinkgo() - logrus.AddHook(&logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) } func TestIPSets(t *testing.T) { diff --git a/felix/ipsets/utils_for_test.go b/felix/ipsets/utils_for_test.go index f7babe06af5..74050c9ac08 100644 --- a/felix/ipsets/utils_for_test.go +++ b/felix/ipsets/utils_for_test.go @@ -675,11 +675,22 @@ func (c *listCmd) main() { defer func() { log.WithField("result", result).Info("list command main exiting") if c.Stdout != nil { - c.Stdout.Close() + err := c.Stdout.Close() + if err != nil && result == nil { + result = err + } } c.resultC <- result }() + writef := func(s string, args ...any) { + _, err := fmt.Fprintf(c.Stdout, s, args...) + if err != nil && result == nil { + log.WithError(err).Info("List command hit write error.") + result = err + } + } + if c.Dataplane.FailAllLists { log.Info("Simulating persistent failure of ipset list") result = permanentFailure @@ -715,7 +726,7 @@ func (c *listCmd) main() { result = fmt.Errorf("ipset %v does not exists", c.SetName) return } - fmt.Fprintf(c.Stdout, "Name: %s\n", c.SetName) + writef("Name: %s\n", c.SetName) meta, ok := c.Dataplane.IPSetMetadata[c.SetName] if !ok { // Default metadata for IP sets created by tests. @@ -726,18 +737,18 @@ func (c *listCmd) main() { MaxSize: 1234, } } - fmt.Fprintf(c.Stdout, "Type: %s\n", meta.Type) + writef("Type: %s\n", meta.Type) if meta.Type == IPSetTypeBitmapPort { - fmt.Fprintf(c.Stdout, "Header: family %s range %d-%d\n", meta.Family, meta.RangeMin, meta.RangeMax) + writef("Header: family %s range %d-%d\n", meta.Family, meta.RangeMin, meta.RangeMax) } else if meta.Type == "unknown:type" { - fmt.Fprintf(c.Stdout, "Header: floop\n") + writef("Header: floop\n") } else { - fmt.Fprintf(c.Stdout, "Header: family %s hashsize 1024 maxelem %d\n", meta.Family, meta.MaxSize) + writef("Header: family %s hashsize 1024 maxelem %d\n", meta.Family, meta.MaxSize) } - fmt.Fprint(c.Stdout, "Field: foobar\n") // Dummy field, should get ignored. - fmt.Fprint(c.Stdout, "Members:\n") + writef("Field: foobar\n") // Dummy field, should get ignored. + writef("Members:\n") members.Iter(func(member string) error { - fmt.Fprintf(c.Stdout, "%s\n", member) + writef("%s\n", member) return nil }) } diff --git a/felix/iptables/match_builder.go b/felix/iptables/match_builder.go index bff355f1d76..cf521bd5b1d 100644 --- a/felix/iptables/match_builder.go +++ b/felix/iptables/match_builder.go @@ -235,6 +235,10 @@ func (m matchCriteria) NotSourcePorts(ports ...uint16) generictables.MatchCriter return append(m, fmt.Sprintf("-m multiport ! --source-ports %s", portsString)) } +func (m matchCriteria) DestPort(port uint16) generictables.MatchCriteria { + return append(m, fmt.Sprintf("--dport %v", port)) +} + func (m matchCriteria) DestPorts(ports ...uint16) generictables.MatchCriteria { portsString := PortsToMultiport(ports) return append(m, fmt.Sprintf("-m multiport --destination-ports %s", portsString)) diff --git a/felix/iptables/restore_buffer.go b/felix/iptables/restore_buffer.go index e1b6073d5b4..c1c432144b9 100644 --- a/felix/iptables/restore_buffer.go +++ b/felix/iptables/restore_buffer.go @@ -114,7 +114,7 @@ func (b *RestoreInputBuilder) WriteForwardReference(chainName string) { // Panics if there is no open transaction. func (b *RestoreInputBuilder) WriteLine(line string) { b.maybeWriteTransactionOpener() - b.writeFormattedLine(line) + b.writeFormattedLine("%s", line) } // GetBytesAndReset returns the contents of the buffer and, as a side effect, resets the buffer. For performance, diff --git a/felix/jitter/jittered_ticker.go b/felix/jitter/jittered_ticker.go index 38fae59c34c..817f7393d5b 100644 --- a/felix/jitter/jittered_ticker.go +++ b/felix/jitter/jittered_ticker.go @@ -16,6 +16,7 @@ package jitter import ( "math/rand" + "sync" "time" log "github.com/sirupsen/logrus" @@ -24,6 +25,7 @@ import ( // Ticker tries to emit events on channel C at minDuration intervals plus up to maxJitter. type Ticker struct { C <-chan time.Time + stopOnce sync.Once stop chan bool MinDuration time.Duration MaxJitter time.Duration @@ -48,17 +50,22 @@ func NewTicker(minDuration time.Duration, maxJitter time.Duration) *Ticker { } func (t *Ticker) loop(c chan time.Time) { -tickLoop: + timer := time.NewTimer(t.calculateDelay()) + defer timer.Stop() + + var cMask chan time.Time + var ts time.Time for { - time.Sleep(t.calculateDelay()) - // Send best-effort then go back to sleep. select { + case ts = <-timer.C: + cMask = c + timer.Reset(t.calculateDelay()) case <-t.stop: - log.Info("Stopping jittered ticker") + log.Debug("Stopping jitter.Ticker") close(c) - break tickLoop - case c <- time.Now(): - default: + return + case cMask <- ts: + cMask = nil } } } @@ -70,7 +77,9 @@ func (t *Ticker) calculateDelay() time.Duration { } func (t *Ticker) Stop() { - t.stop <- true + t.stopOnce.Do(func() { + close(t.stop) + }) } func (t *Ticker) Channel() <-chan time.Time { @@ -81,7 +90,7 @@ func (t *Ticker) Done() chan bool { return t.stop } -type JitterTicker interface { +type TickerInterface interface { Stop() Channel() <-chan time.Time Done() chan bool diff --git a/felix/jitter/jittered_ticker_test.go b/felix/jitter/jittered_ticker_test.go index b5f724cf7b1..355a4742de0 100644 --- a/felix/jitter/jittered_ticker_test.go +++ b/felix/jitter/jittered_ticker_test.go @@ -28,8 +28,7 @@ var _ = Describe("Real 20ms + 10ms Ticker", func() { var startTime time.Time BeforeEach(func() { startTime = time.Now() - ticker = NewTicker(20*time.Millisecond, - 10*time.Millisecond) + ticker = NewTicker(20*time.Millisecond, 10*time.Millisecond) }) AfterEach(func() { ticker.Stop() @@ -64,6 +63,15 @@ var _ = Describe("Real 20ms + 10ms Ticker", func() { }, 1) }) +var _ = Describe("Ticker.Stop()", func() { + It("should interrupt the current tick", func() { + ticker := NewTicker(5*time.Second, 10*time.Millisecond) + startTime := time.Now() + ticker.Stop() + Expect(time.Since(startTime)).To(BeNumerically("<", 100*time.Millisecond)) + }) +}) + var _ = Describe("Delay calculation", func() { var ticker *Ticker BeforeEach(func() { diff --git a/felix/labelindex/label_inheritance_index.go b/felix/labelindex/label_inheritance_index.go index 8f2881c21c4..fd986938d8c 100644 --- a/felix/labelindex/label_inheritance_index.go +++ b/felix/labelindex/label_inheritance_index.go @@ -179,7 +179,10 @@ func (idx *InheritIndex) UpdateSelector(id interface{}, sel selector.Selector) { log.WithField("selID", id).Debug("Skipping unchanged selector") return } - log.WithField("selID", id).Info("Updating selector") + log.WithFields(log.Fields{ + "id": id, + "selector": sel, + }).Info("Updating selector") idx.scanAllLabels(id, sel) idx.selectorsById[id] = sel } diff --git a/felix/logutils/logutils.go b/felix/logutils/logutils.go index 844b3167097..cbb150e27e1 100644 --- a/felix/logutils/logutils.go +++ b/felix/logutils/logutils.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -51,12 +51,8 @@ func ConfigureEarlyLogging() { // Log to stdout. This prevents fluentd, for example, from interpreting all our logs as errors by default. log.SetOutput(os.Stdout) - // Replace logrus' formatter with a custom one using our time format, - // shared with the Python code. - log.SetFormatter(&logutils.Formatter{Component: "felix"}) - - // Install a hook that adds file/line no information. - log.AddHook(&logutils.ContextHook{}) + // Set up logging formatting. + logutils.ConfigureFormatter("felix") // First try the early-only environment variable. Since the normal // config processing doesn't know about that variable, normal config @@ -144,10 +140,6 @@ func ConfigureLogging(configParams *config.Config) { // hook above to fan out logs to multiple destinations. log.SetOutput(&logutils.NullWriter{}) - // Since we push our logs onto a second thread via a channel, we can disable the - // Logger's built-in mutex completely. - log.StandardLogger().SetNoLock() - // Do any deferred error logging. if fileDirErr != nil { log.WithError(fileDirErr).WithField("file", configParams.LogFilePath). diff --git a/felix/netlinkshim/mocknetlink/netlink.go b/felix/netlinkshim/mocknetlink/netlink.go index 2f530353efe..9914799b2e3 100644 --- a/felix/netlinkshim/mocknetlink/netlink.go +++ b/felix/netlinkshim/mocknetlink/netlink.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -121,11 +121,11 @@ const ( FailNextLinkByName FailNextLinkByNameNotFound FailNextRouteList + FailNextRouteListEINTR FailNextRouteAddOrReplace FailNextRouteAdd FailNextRouteReplace FailNextRouteDel - FailNextAddARP FailNextNeighSet FailNextNeighDel FailNextNeighList @@ -159,7 +159,7 @@ var RoutetableFailureScenarios = []FailFlags{ FailNextRouteList, FailNextRouteAdd, FailNextRouteDel, - FailNextAddARP, + FailNextNeighSet, FailNextNewNetlink, FailNextSetSocketTimeout, FailNextSetStrict, @@ -191,9 +191,6 @@ func (f FailFlags) String() string { if f&FailNextRouteDel != 0 { parts = append(parts, "FailNextRouteDel") } - if f&FailNextAddARP != 0 { - parts = append(parts, "FailNextAddARP") - } if f&FailNextNeighSet != 0 { parts = append(parts, "FailNextNeighSet") } @@ -308,8 +305,6 @@ type MockNetlinkDataplane struct { SetStrictCheckErr error DeleteInterfaceAfterLinkByName bool - addedArpEntries set.Set[string] - mutex *sync.Mutex deletedConntrackEntries set.Set[ip.Addr] ConntrackSleep time.Duration @@ -342,7 +337,6 @@ func (d *MockNetlinkDataplane) ResetDeltas() { d.AddedRouteKeys = set.New[string]() d.DeletedRouteKeys = set.New[string]() d.UpdatedRouteKeys = set.New[string]() - d.addedArpEntries = set.New[string]() d.NumLinkAddCalls = 0 d.NumLinkDeleteCalls = 0 d.NumNewNetlinkCalls = 0 @@ -399,6 +393,10 @@ func (d *MockNetlinkDataplane) AddIface(idx int, name string, up bool, running b return link.copy() } +func (d *MockNetlinkDataplane) DelIface(name string) { + delete(d.NameToLink, name) +} + func (d *MockNetlinkDataplane) SetIface(name string, up bool, running bool) { link, ok := d.NameToLink[name] ExpectWithOffset(1, ok).To(BeTrue(), "SetIface called with unknown interface "+name) @@ -725,6 +723,21 @@ func (d *MockNetlinkDataplane) RuleDel(rule *netlink.Rule) error { return nil } +func (d *MockNetlinkDataplane) RouteListFilteredIter( + family int, + filter *netlink.Route, + filterMask uint64, + f func(netlink.Route) (cont bool), +) error { + routes, err := d.RouteListFiltered(family, filter, filterMask) + for _, route := range routes { + if !f(route) { + break + } + } + return err +} + func (d *MockNetlinkDataplane) RouteListFiltered(family int, filter *netlink.Route, filterMask uint64) ([]netlink.Route, error) { d.mutex.Lock() defer d.mutex.Unlock() @@ -799,6 +812,11 @@ func (d *MockNetlinkDataplane) RouteListFiltered(family int, filter *netlink.Rou } routes = append(routes, route) } + + if d.shouldFail(FailNextRouteListEINTR) { + return routes[:len(routes)/2], unix.EINTR + } + return routes, nil } @@ -919,9 +937,13 @@ func addNeighs(neighMap map[NeighKey]*netlink.Neigh, neighs []netlink.Neigh) { } func (d *MockNetlinkDataplane) ExpectNeighs(family int, neighs ...netlink.Neigh) { + if len(neighs) == 0 { + ExpectWithOffset(1, d.NeighsByFamily[family]).To(HaveLen(0)) + return + } nm := map[NeighKey]*netlink.Neigh{} addNeighs(nm, neighs) - ExpectWithOffset(1, nm).To(Equal(d.NeighsByFamily[family])) + ExpectWithOffset(1, d.NeighsByFamily[family]).To(Equal(nm)) } func (d *MockNetlinkDataplane) NeighAdd(neigh *netlink.Neigh) error { @@ -1052,45 +1074,6 @@ func (d *MockNetlinkDataplane) NeighDel(neigh *netlink.Neigh) error { // ----- Routetable specific Conntrack functions ----- -func (d *MockNetlinkDataplane) AddStaticArpEntry(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) error { - d.mutex.Lock() - defer d.mutex.Unlock() - defer GinkgoRecover() - - if d.shouldFail(FailNextAddARP) { - return SimulatedError - } - log.WithFields(log.Fields{ - "cidr": cidr, - "destMac": destMAC, - "ifaceName": ifaceName, - }).Info("Mock dataplane: adding ARP entry") - d.addedArpEntries.Add(getArpKey(cidr, destMAC, ifaceName)) - - if d.NeighsByFamily[unix.AF_INET] == nil { - d.NeighsByFamily[unix.AF_INET] = map[NeighKey]*netlink.Neigh{} - } - - linkIndex := d.NameToLink[ifaceName].LinkAttrs.Index - d.NeighsByFamily[unix.AF_INET][NeighKey{ - LinkIndex: linkIndex, - MAC: destMAC.String(), - IP: cidr.Addr(), - }] = &netlink.Neigh{ - Family: unix.AF_INET, - LinkIndex: linkIndex, - State: netlink.NUD_PERMANENT, - Type: unix.RTN_UNICAST, - IP: cidr.Addr().AsNetIP(), - HardwareAddr: destMAC, - } - return nil -} - -func (d *MockNetlinkDataplane) HasStaticArpEntry(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) bool { - return d.addedArpEntries.Contains(getArpKey(cidr, destMAC, ifaceName)) -} - func (d *MockNetlinkDataplane) RemoveConntrackFlows(ipVersion uint8, ipAddr net.IP) { log.WithFields(log.Fields{ "ipVersion": ipVersion, @@ -1180,7 +1163,3 @@ func (l *MockLink) copy() *MockLink { WireguardPeers: wgPeersCopy, } } - -func getArpKey(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) string { - return cidr.String() + ":" + destMAC.String() + ":" + ifaceName -} diff --git a/felix/netlinkshim/netlink.go b/felix/netlinkshim/netlink.go index 3bcf5d89a28..a87d1d60256 100644 --- a/felix/netlinkshim/netlink.go +++ b/felix/netlinkshim/netlink.go @@ -15,10 +15,12 @@ package netlinkshim import ( + "errors" "syscall" "time" "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" ) type Interface interface { @@ -31,6 +33,7 @@ type Interface interface { LinkSetMTU(link netlink.Link, mtu int) error LinkSetUp(link netlink.Link) error RouteListFiltered(family int, filter *netlink.Route, filterMask uint64) ([]netlink.Route, error) + RouteListFilteredIter(family int, filter *netlink.Route, filterMask uint64, f func(netlink.Route) (cont bool)) error RouteAdd(route *netlink.Route) error RouteReplace(route *netlink.Route) error RouteDel(route *netlink.Route) error @@ -47,6 +50,164 @@ type Interface interface { NeighDel(a *netlink.Neigh) error } +type RealNetlink struct { + nlHandle *netlink.Handle +} + func NewRealNetlink() (Interface, error) { - return netlink.NewHandle(syscall.NETLINK_ROUTE) + nlHandle, err := netlink.NewHandle(syscall.NETLINK_ROUTE) + if err != nil { + return nil, err + } + return &RealNetlink{ + nlHandle: nlHandle, + }, nil +} + +func (r *RealNetlink) SetSocketTimeout(to time.Duration) error { + return r.nlHandle.SetSocketTimeout(to) +} + +func (r *RealNetlink) SetStrictCheck(b bool) error { + return r.nlHandle.SetStrictCheck(b) +} + +func (r *RealNetlink) LinkList() ([]netlink.Link, error) { + retries := 3 + for { + links, err := r.nlHandle.LinkList() + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + retries-- + continue + } + } + return links, err + } +} + +func (r *RealNetlink) LinkByName(name string) (netlink.Link, error) { + return r.nlHandle.LinkByName(name) +} + +func (r *RealNetlink) LinkAdd(link netlink.Link) error { + return r.nlHandle.LinkAdd(link) +} + +func (r *RealNetlink) LinkDel(link netlink.Link) error { + return r.nlHandle.LinkDel(link) +} + +func (r *RealNetlink) LinkSetMTU(link netlink.Link, mtu int) error { + return r.nlHandle.LinkSetMTU(link, mtu) +} + +func (r *RealNetlink) LinkSetUp(link netlink.Link) error { + return r.nlHandle.LinkSetUp(link) +} + +func (r *RealNetlink) RouteListFiltered(family int, filter *netlink.Route, filterMask uint64) ([]netlink.Route, error) { + retries := 3 + for { + routes, err := r.nlHandle.RouteListFiltered(family, filter, filterMask) + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + retries-- + continue + } + } + return routes, err + } +} + +func (r *RealNetlink) RouteListFilteredIter(family int, filter *netlink.Route, filterMask uint64, f func(netlink.Route) (cont bool)) error { + // Can't retry inline because that would confuse the callback function. + return r.nlHandle.RouteListFilteredIter(family, filter, filterMask, f) +} + +func (r *RealNetlink) RouteAdd(route *netlink.Route) error { + return r.nlHandle.RouteAdd(route) +} + +func (r *RealNetlink) RouteReplace(route *netlink.Route) error { + return r.nlHandle.RouteReplace(route) +} + +func (r *RealNetlink) RouteDel(route *netlink.Route) error { + return r.nlHandle.RouteDel(route) +} + +func (r *RealNetlink) AddrList(link netlink.Link, family int) ([]netlink.Addr, error) { + retries := 3 + for { + addrs, err := r.nlHandle.AddrList(link, family) + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + retries-- + continue + } + } + return addrs, err + } +} + +func (r *RealNetlink) AddrAdd(link netlink.Link, addr *netlink.Addr) error { + return r.nlHandle.AddrAdd(link, addr) +} + +func (r *RealNetlink) AddrDel(link netlink.Link, addr *netlink.Addr) error { + return r.nlHandle.AddrDel(link, addr) +} + +func (r *RealNetlink) RuleList(family int) ([]netlink.Rule, error) { + retries := 3 + for { + rules, err := r.nlHandle.RuleList(family) + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + retries-- + continue + } + } + return rules, err + } +} + +func (r *RealNetlink) RuleAdd(rule *netlink.Rule) error { + return r.nlHandle.RuleAdd(rule) +} + +func (r *RealNetlink) RuleDel(rule *netlink.Rule) error { + return r.nlHandle.RuleDel(rule) +} + +func (r *RealNetlink) Delete() { + //nolint:staticcheck + r.nlHandle.Delete() +} + +func (r *RealNetlink) NeighAdd(neigh *netlink.Neigh) error { + return r.nlHandle.NeighAdd(neigh) +} + +func (r *RealNetlink) NeighList(linkIndex, family int) ([]netlink.Neigh, error) { + retries := 3 + for { + neighs, err := r.nlHandle.NeighList(linkIndex, family) + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + retries-- + continue + } + } + return neighs, err + } +} + +func (r *RealNetlink) NeighSet(a *netlink.Neigh) error { + return r.nlHandle.NeighSet(a) +} + +func (r *RealNetlink) NeighDel(a *netlink.Neigh) error { + return r.nlHandle.NeighDel(a) } diff --git a/felix/nftables/actions.go b/felix/nftables/actions.go index 2edb69473fa..65186aae749 100644 --- a/felix/nftables/actions.go +++ b/felix/nftables/actions.go @@ -337,7 +337,7 @@ type SetMaskedMarkAction struct { } func (c SetMaskedMarkAction) ToFragment(features *environment.Features) string { - return fmt.Sprintf("meta mark set mark or %#x", (c.Mark & c.Mask)) + return fmt.Sprintf("meta mark set mark & %#x ^ %#x", (c.Mask ^ 0xffffffff), c.Mark) } func (c SetMaskedMarkAction) String() string { @@ -400,8 +400,7 @@ func (c SetConnMarkAction) ToFragment(features *environment.Features) string { // If Mask field is ignored, default to full mark. return fmt.Sprintf("ct mark set %#x", c.Mark) } - notMask := c.Mask ^ 0xffffffff - return fmt.Sprintf("ct mark set ct mark xor %#x & %#x", c.Mark, notMask) + return fmt.Sprintf("ct mark set ct mark & %#x ^ %#x", (c.Mask ^ 0xffffffff), c.Mark) } func (c SetConnMarkAction) String() string { diff --git a/felix/nftables/actions_test.go b/felix/nftables/actions_test.go index 3c8d6ce302c..7b0af097c38 100644 --- a/felix/nftables/actions_test.go +++ b/felix/nftables/actions_test.go @@ -40,9 +40,10 @@ var _ = DescribeTable("Actions", Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{}, "masquerade fully-random"), Entry("ClearMarkAction", environment.Features{}, ClearMarkAction{Mark: 0x1000}, "meta mark set mark & 0xffffefff"), Entry("SetMarkAction", environment.Features{}, SetMarkAction{Mark: 0x1000}, "meta mark set mark or 0x1000"), - Entry("SetMaskedMarkAction", environment.Features{}, SetMaskedMarkAction{Mark: 0x1000, Mask: 0xf000}, "meta mark set mark or 0x1000"), + Entry("SetMaskedMarkAction", environment.Features{}, SetMaskedMarkAction{Mark: 0x1000, Mask: 0xf000}, "meta mark set mark & 0xffff0fff ^ 0x1000"), Entry("SaveConnMarkAction", environment.Features{}, SaveConnMarkAction{SaveMask: 0x100}, "ct mark set mark & 0x100"), Entry("RestoreConnMarkAction", environment.Features{}, RestoreConnMarkAction{RestoreMask: 0x100}, "meta mark set ct mark & 0x100"), Entry("SaveConnMarkAction", environment.Features{}, SaveConnMarkAction{}, "ct mark set mark"), Entry("RestoreConnMarkAction", environment.Features{}, RestoreConnMarkAction{}, "meta mark set ct mark"), + Entry("SetConnMarkAction", environment.Features{}, SetConnMarkAction{Mark: 0x1000, Mask: 0xf000}, "ct mark set ct mark & 0xffff0fff ^ 0x1000"), ) diff --git a/felix/nftables/ipsets.go b/felix/nftables/ipsets.go index 0f9b13f1931..0e5ff3b3292 100644 --- a/felix/nftables/ipsets.go +++ b/felix/nftables/ipsets.go @@ -569,7 +569,7 @@ func (s *IPSets) NFTablesSet(name string) *knftables.Set { return nil } - flags := make([]knftables.SetFlag, 0, 1) + var flags []knftables.SetFlag switch metadata.Type { case ipsets.IPSetTypeHashIPPort: // IP and port sets don't support the interval flag. diff --git a/felix/nftables/ipsets_test.go b/felix/nftables/ipsets_test.go index 5c51a6dbfed..9f680589f40 100644 --- a/felix/nftables/ipsets_test.go +++ b/felix/nftables/ipsets_test.go @@ -21,6 +21,7 @@ import ( "sigs.k8s.io/knftables" . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" "github.com/projectcalico/calico/felix/ipsets" @@ -201,18 +202,169 @@ var _ = Describe("IPSets with empty data plane", func() { &knftables.Element{Set: "cali40unsupported-set", Key: []string{"10.0.0.1"}}, )) }) +}) - It("should program a hash:net,net IP set", func() { - meta := ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNetNet} - s.AddOrReplaceIPSet(meta, []string{"10.0.0.0/32,11.0.0.0/32"}) +var _ = DescribeTable("IPSets programming v4", + func(meta ipsets.IPSetMetadata, members []string, expected []*knftables.Element) { + f := NewFake(knftables.IPv4Family, "calico") + ipv := ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil) + s := NewIPSets(ipv, f, logutils.NewSummarizer("test loop")) + s.AddOrReplaceIPSet(meta, members) Expect(s.ApplyUpdates).NotTo(Panic()) + + // Read it back. sets, err := f.List(context.Background(), "sets") Expect(err).NotTo(HaveOccurred()) - Expect(sets).To(Equal([]string{"cali40test"})) + Expect(sets).To(Equal([]string{"cali40" + meta.SetID})) - members, err := f.ListElements(context.Background(), "set", "cali40test") + m, err := f.ListElements(context.Background(), "set", "cali40"+meta.SetID) Expect(err).NotTo(HaveOccurred()) - Expect(members).To(HaveLen(1)) - Expect(members[0].Key).To(Equal([]string{"10.0.0.0", "11.0.0.0"})) - }) -}) + Expect(m).To(ContainElements(expected)) + + // Trigger a resync to make sure we can handle it. + s.QueueResync() + Expect(s.ApplyUpdates).NotTo(Panic()) + + // Read it back again. + m, err = f.ListElements(context.Background(), "set", "cali40"+meta.SetID) + Expect(err).NotTo(HaveOccurred()) + Expect(m).To(ContainElements(expected)) + }, + + Entry( + ipsets.IPSetTypeHashIP, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashIP}, []string{"10.0.0.1"}, + []*knftables.Element{{Set: "cali40test", Key: []string{"10.0.0.1"}}}, + ), + Entry( + ipsets.IPSetTypeHashNet, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNet}, []string{"10.0.0.0/24"}, + []*knftables.Element{{Set: "cali40test", Key: []string{"10.0.0.0/24"}}}, + ), + Entry( + ipsets.IPSetTypeHashIPPort, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashIPPort}, []string{"1.2.3.4,tcp:81"}, + []*knftables.Element{{Set: "cali40test", Key: []string{"1.2.3.4", "tcp", "81"}}}, + ), + Entry( + ipsets.IPSetTypeHashNetNet, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNetNet}, []string{"10.0.0.0/32,10.0.0.0/32"}, + []*knftables.Element{{Set: "cali40test", Key: []string{"10.0.0.0", "10.0.0.0"}}}, + ), + Entry( + ipsets.IPSetTypeBitmapPort, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeBitmapPort}, []string{"v4,80"}, + []*knftables.Element{{Set: "cali40test", Key: []string{"80"}}}, + ), +) + +var _ = DescribeTable("IPSets programming v6", + func(meta ipsets.IPSetMetadata, members []string, expected []*knftables.Element) { + f := NewFake(knftables.IPv4Family, "calico") + ipv := ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil) + s := NewIPSets(ipv, f, logutils.NewSummarizer("test loop")) + s.AddOrReplaceIPSet(meta, members) + Expect(s.ApplyUpdates).NotTo(Panic()) + + // Read it back. + sets, err := f.List(context.Background(), "sets") + Expect(err).NotTo(HaveOccurred()) + Expect(sets).To(Equal([]string{"cali60" + meta.SetID})) + + m, err := f.ListElements(context.Background(), "set", "cali60"+meta.SetID) + Expect(err).NotTo(HaveOccurred()) + Expect(m).To(ContainElements(expected)) + + // Trigger a resync to make sure we can handle it. + s.QueueResync() + Expect(s.ApplyUpdates).NotTo(Panic()) + + // Read it back again. + m, err = f.ListElements(context.Background(), "set", "cali60"+meta.SetID) + Expect(err).NotTo(HaveOccurred()) + Expect(m).To(ContainElements(expected)) + }, + + Entry( + ipsets.IPSetTypeHashIP, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashIP}, []string{"2001:db8::1"}, + []*knftables.Element{{Set: "cali60test", Key: []string{"2001:db8::1"}}}, + ), + Entry( + ipsets.IPSetTypeHashNet, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNet}, []string{"2001:db8::/64"}, + []*knftables.Element{{Set: "cali60test", Key: []string{"2001:db8::/64"}}}, + ), + Entry( + ipsets.IPSetTypeHashIPPort, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashIPPort}, []string{"2001:db8::1,tcp:81"}, + []*knftables.Element{{Set: "cali60test", Key: []string{"2001:db8::1", "tcp", "81"}}}, + ), + Entry( + ipsets.IPSetTypeHashNetNet, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNetNet}, []string{"2001:db8::/128,2001:db8::/128"}, + []*knftables.Element{{Set: "cali60test", Key: []string{"2001:db8::", "2001:db8::"}}}, + ), + Entry( + ipsets.IPSetTypeBitmapPort, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeBitmapPort}, []string{"v6,80"}, + []*knftables.Element{{Set: "cali60test", Key: []string{"80"}}}, + ), +) + +var _ = DescribeTable("CanonicalizeMember", + func(setType ipsets.IPSetType, member string, strVal string, key []string) { + canon := CanonicaliseMember(setType, member) + Expect(canon.String()).To(Equal(strVal)) + Expect(canon.Key()).To(Equal(key)) + }, + + Entry(ipsets.IPSetTypeHashIP, ipsets.IPSetTypeHashIP, "192.168.0.1/32", "192.168.0.1", []string{"192.168.0.1"}), + Entry(ipsets.IPSetTypeHashIP, ipsets.IPSetTypeHashIP, "fe80::1/128", "fe80::1", []string{"fe80::1"}), + Entry(ipsets.IPSetTypeHashNet, ipsets.IPSetTypeHashNet, "10.0.0.0/24", "10.0.0.0/24", []string{"10.0.0.0/24"}), + Entry(ipsets.IPSetTypeHashNet, ipsets.IPSetTypeHashNet, "2001:db8::/64", "2001:db8::/64", []string{"2001:db8::/64"}), + Entry(ipsets.IPSetTypeHashIPPort, ipsets.IPSetTypeHashIPPort, "192.168.0.1,tcp:80", "192.168.0.1,tcp:80", []string{"192.168.0.1", "tcp", "80"}), + Entry(ipsets.IPSetTypeHashIPPort, ipsets.IPSetTypeHashIPPort, "fe80::1,udp:53", "fe80::1,udp:53", []string{"fe80::1", "udp", "53"}), + Entry(ipsets.IPSetTypeHashNetNet, ipsets.IPSetTypeHashNetNet, "10.0.0.1/32,10.0.0.1/32", "10.0.0.1/32 . 10.0.0.1/32", []string{"10.0.0.1", "10.0.0.1"}), + Entry(ipsets.IPSetTypeHashNetNet, ipsets.IPSetTypeHashNetNet, "2001:db8::1/128,2001:db8::1/128", "2001:db8::1/128 . 2001:db8::1/128", []string{"2001:db8::1", "2001:db8::1"}), + Entry(ipsets.IPSetTypeBitmapPort, ipsets.IPSetTypeBitmapPort, "v4,80", "80", []string{"80"}), + Entry(ipsets.IPSetTypeBitmapPort, ipsets.IPSetTypeBitmapPort, "v6,80", "80", []string{"80"}), + Entry(ipsets.IPSetTypeBitmapPort, ipsets.IPSetTypeBitmapPort, "80", "80", []string{"80"}), +) + +var _ = DescribeTable("NFTablesSet", + func(meta ipsets.IPSetMetadata, exp *knftables.Set) { + f := NewFake(knftables.IPv4Family, "calico") + ipv := ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil) + s := NewIPSets(ipv, f, logutils.NewSummarizer("test loop")) + s.AddOrReplaceIPSet(meta, []string{}) + Expect(s.ApplyUpdates).NotTo(Panic()) + Expect(s.NFTablesSet(fmt.Sprintf("cali40%s", meta.SetID))).To(Equal(exp)) + }, + + Entry( + ipsets.IPSetTypeHashIP, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashIP}, + &knftables.Set{Name: "cali40test", Type: "ipv4_addr"}, + ), + Entry( + ipsets.IPSetTypeHashNet, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNet}, + &knftables.Set{Name: "cali40test", Type: "ipv4_addr", Flags: []knftables.SetFlag{knftables.IntervalFlag}}, + ), + Entry( + ipsets.IPSetTypeHashIPPort, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashIPPort}, + &knftables.Set{Name: "cali40test", Type: "ipv4_addr . inet_proto . inet_service"}, + ), + Entry( + ipsets.IPSetTypeHashNetNet, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeHashNetNet}, + &knftables.Set{Name: "cali40test", Type: "ipv4_addr . ipv4_addr"}, + ), + Entry( + ipsets.IPSetTypeBitmapPort, + ipsets.IPSetMetadata{SetID: "test", Type: ipsets.IPSetTypeBitmapPort}, + &knftables.Set{Name: "cali40test", Type: "inet_service"}, + ), +) diff --git a/felix/nftables/match_builder.go b/felix/nftables/match_builder.go index 309d483f4b5..e1d9304c53f 100644 --- a/felix/nftables/match_builder.go +++ b/felix/nftables/match_builder.go @@ -395,6 +395,11 @@ func (m nftMatch) NotSourcePorts(ports ...uint16) generictables.MatchCriteria { return m } +func (m nftMatch) DestPort(port uint16) generictables.MatchCriteria { + m.clauses = append(m.clauses, fmt.Sprintf("%s dport %v", m.transportProto(), port)) + return m +} + func (m nftMatch) DestPorts(ports ...uint16) generictables.MatchCriteria { m.clauses = append(m.clauses, fmt.Sprintf("%s dport %s", m.transportProto(), PortsToMultiport(ports))) return m diff --git a/felix/nftables/table.go b/felix/nftables/table.go index 3a5520ae820..66da80735f1 100644 --- a/felix/nftables/table.go +++ b/felix/nftables/table.go @@ -56,14 +56,53 @@ var ( filterType = knftables.FilterType routeType = knftables.RouteType - // Each type of hook requires a specific filterPriority in order to be executed in the correct order. + // Each type of hook requires a specific filterPriority to be executed in the correct order. + // We also want to make sure that our priorities are unique, as to avoid unspecified ordering that can + // occur when two hooks share the same priority. + // + // Calico and kube-proxy share the following hooks, with relative priorities shown: + // + // INPUT: + // |------------|--------------|--------| + // | calico | mangle-INPUT | -150 + // | kube-proxy | filter-input | -110 + // | calico | filter-INPUT | 0 + // + // FORWARD: + // |------------|----------------|--------| + // | calico | mangle-FORWARD | -150 + // | kube-proxy | filter-forward | -110 + // | calico | filter-FORWARD | 0 + // + // OUTPUT: + // |------------|-------------------------|--------| + // | calico | mangle-OUTPUT | -150 + // | kube-proxy | filter-output | -110 + // | calico | filter-output-post-dnat | -90 + // | calico | filter-OUTPUT | 0 + // + // PREROUTING: + // |------------|-------------------|--------| + // | calico | raw-PREROUTING | -300 + // | calico | mangle-PREROUTING | -150 + // | kube-proxy | filter-prerouting | -110 + // | calico | nat-PREROUTING | -100 + // + // POSTROUTING: + // |------------|--------------------|--------| + // | calico | mangle-POSTROUTING | -150 + // | kube-proxy | nat-postrouting | 100 + // | calico | nat-POSTROUTING | 110 + // + // The full set of kube-proxy base chains can be found here: + // - https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/nftables/proxier.go filterPriority = knftables.FilterPriority rawPriority = knftables.RawPriority manglePriority = knftables.ManglePriority - snatPriority = knftables.SNATPriority + snatPriority = knftables.SNATPriority + "+10" dnatPriority = knftables.DNATPriority - // Calico uses a single nftables with a variety of hooks. + // Calico uses a single nftables table with a variety of hooks. // The top level base chains are laid out below. baseChains = map[string]knftables.Chain{ // Filter hook. diff --git a/felix/policysync/processor_test.go b/felix/policysync/processor_test.go index 7c34e8885e8..5c590d3606a 100644 --- a/felix/policysync/processor_test.go +++ b/felix/policysync/processor_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,9 +27,11 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/types" + "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/resolver" "github.com/projectcalico/calico/felix/policysync" "github.com/projectcalico/calico/felix/proto" @@ -41,6 +43,10 @@ const ProfileName = "testpro" const TierName = "testtier" const PolicyName = "testpolicy" +func init() { + resolver.SetDefaultScheme("passthrough") +} + var _ = Describe("Processor", func() { var uut *policysync.Processor var updates chan interface{} @@ -730,7 +736,7 @@ var _ = Describe("Processor", func() { opts := getDialOptions() var err error - clientConn, err = grpc.Dial(path.Join(socketDir, ListenerSocket), opts...) + clientConn, err = grpc.NewClient(path.Join(socketDir, ListenerSocket), opts...) Expect(err).ToNot(HaveOccurred()) syncClient = proto.NewPolicySyncClient(clientConn) diff --git a/felix/proto/felixbackend.pb.go b/felix/proto/felixbackend.pb.go index f8eb772e101..96b30fcb7c5 100644 --- a/felix/proto/felixbackend.pb.go +++ b/felix/proto/felixbackend.pb.go @@ -3235,6 +3235,7 @@ type TierInfo struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` IngressPolicies []string `protobuf:"bytes,2,rep,name=ingress_policies,json=ingressPolicies" json:"ingress_policies,omitempty"` EgressPolicies []string `protobuf:"bytes,3,rep,name=egress_policies,json=egressPolicies" json:"egress_policies,omitempty"` + DefaultAction string `protobuf:"bytes,4,opt,name=default_action,json=defaultAction,proto3" json:"default_action,omitempty"` } func (m *TierInfo) Reset() { *m = TierInfo{} } @@ -3263,6 +3264,13 @@ func (m *TierInfo) GetEgressPolicies() []string { return nil } +func (m *TierInfo) GetDefaultAction() string { + if m != nil { + return m.DefaultAction + } + return "" +} + type NatInfo struct { ExtIp string `protobuf:"bytes,1,opt,name=ext_ip,json=extIp,proto3" json:"ext_ip,omitempty"` IntIp string `protobuf:"bytes,2,opt,name=int_ip,json=intIp,proto3" json:"int_ip,omitempty"` @@ -4261,7 +4269,7 @@ type ServiceUpdate struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` - ClusterIp string `protobuf:"bytes,4,opt,name=cluster_ip,json=clusterIp,proto3" json:"cluster_ip,omitempty"` + ClusterIps []string `protobuf:"bytes,4,rep,name=cluster_ips,json=clusterIps" json:"cluster_ips,omitempty"` LoadbalancerIp string `protobuf:"bytes,5,opt,name=loadbalancer_ip,json=loadbalancerIp,proto3" json:"loadbalancer_ip,omitempty"` ExternalIps []string `protobuf:"bytes,6,rep,name=external_ips,json=externalIps" json:"external_ips,omitempty"` Ports []*ServicePort `protobuf:"bytes,7,rep,name=ports" json:"ports,omitempty"` @@ -4293,11 +4301,11 @@ func (m *ServiceUpdate) GetType() string { return "" } -func (m *ServiceUpdate) GetClusterIp() string { +func (m *ServiceUpdate) GetClusterIps() []string { if m != nil { - return m.ClusterIp + return m.ClusterIps } - return "" + return nil } func (m *ServiceUpdate) GetLoadbalancerIp() string { @@ -7123,6 +7131,12 @@ func (m *TierInfo) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], s) } } + if len(m.DefaultAction) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintFelixbackend(dAtA, i, uint64(len(m.DefaultAction))) + i += copy(dAtA[i:], m.DefaultAction) + } return i, nil } @@ -8442,11 +8456,20 @@ func (m *ServiceUpdate) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintFelixbackend(dAtA, i, uint64(len(m.Type))) i += copy(dAtA[i:], m.Type) } - if len(m.ClusterIp) > 0 { - dAtA[i] = 0x22 - i++ - i = encodeVarintFelixbackend(dAtA, i, uint64(len(m.ClusterIp))) - i += copy(dAtA[i:], m.ClusterIp) + if len(m.ClusterIps) > 0 { + for _, s := range m.ClusterIps { + dAtA[i] = 0x22 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } } if len(m.LoadbalancerIp) > 0 { dAtA[i] = 0x2a @@ -9728,6 +9751,10 @@ func (m *TierInfo) Size() (n int) { n += 1 + l + sovFelixbackend(uint64(l)) } } + l = len(m.DefaultAction) + if l > 0 { + n += 1 + l + sovFelixbackend(uint64(l)) + } return n } @@ -10292,9 +10319,11 @@ func (m *ServiceUpdate) Size() (n int) { if l > 0 { n += 1 + l + sovFelixbackend(uint64(l)) } - l = len(m.ClusterIp) - if l > 0 { - n += 1 + l + sovFelixbackend(uint64(l)) + if len(m.ClusterIps) > 0 { + for _, s := range m.ClusterIps { + l = len(s) + n += 1 + l + sovFelixbackend(uint64(l)) + } } l = len(m.LoadbalancerIp) if l > 0 { @@ -17217,6 +17246,35 @@ func (m *TierInfo) Unmarshal(dAtA []byte) error { } m.EgressPolicies = append(m.EgressPolicies, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultAction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFelixbackend + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthFelixbackend + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DefaultAction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipFelixbackend(dAtA[iNdEx:]) @@ -21691,7 +21749,7 @@ func (m *ServiceUpdate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterIp", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ClusterIps", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -21716,7 +21774,7 @@ func (m *ServiceUpdate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ClusterIp = string(dAtA[iNdEx:postIndex]) + m.ClusterIps = append(m.ClusterIps, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 5: if wireType != 2 { @@ -22044,269 +22102,271 @@ var ( func init() { proto1.RegisterFile("felixbackend.proto", fileDescriptorFelixbackend) } var fileDescriptorFelixbackend = []byte{ - // 4220 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5b, 0xcd, 0x73, 0x1c, 0x49, - 0x56, 0x57, 0xb7, 0xa4, 0x56, 0xf7, 0xeb, 0xaf, 0x72, 0xea, 0xab, 0x25, 0xdb, 0xb2, 0xa7, 0x3c, - 0xde, 0xd1, 0x78, 0x77, 0x3c, 0x46, 0x23, 0xb7, 0xd7, 0xc3, 0x32, 0x1b, 0x6d, 0xb5, 0x66, 0xd4, - 0x33, 0xb6, 0x24, 0x4a, 0x1a, 0x0d, 0xb3, 0x6c, 0x44, 0x51, 0xaa, 0x4a, 0x49, 0x85, 0xab, 0xab, - 0x6a, 0xaa, 0xb2, 0xf5, 0xb1, 0x9c, 0x80, 0x25, 0x02, 0x82, 0x03, 0x1c, 0x08, 0x82, 0x3f, 0x80, - 0x13, 0xc1, 0x7f, 0xc0, 0x81, 0xeb, 0x6e, 0x70, 0x81, 0xe0, 0x4c, 0x04, 0x31, 0xdc, 0xb8, 0x41, - 0x04, 0x77, 0x22, 0x3f, 0xeb, 0xa3, 0xab, 0x65, 0x99, 0x1d, 0xf6, 0xa4, 0xce, 0x97, 0xef, 0xfd, - 0xf2, 0x97, 0xaf, 0x5e, 0xbe, 0xfc, 0x14, 0xa0, 0x13, 0xec, 0xb9, 0x97, 0xc7, 0x96, 0xfd, 0x1a, - 0xfb, 0xce, 0xe3, 0x30, 0x0a, 0x48, 0x80, 0x66, 0x99, 0x4c, 0x6f, 0x42, 0xfd, 0xe0, 0xca, 0xb7, - 0x0d, 0xfc, 0xcd, 0x08, 0xc7, 0x44, 0xff, 0xa7, 0x25, 0xa8, 0x1f, 0x06, 0x7d, 0x8b, 0x58, 0xa1, - 0x67, 0xf9, 0x18, 0xad, 0xc3, 0x9c, 0xeb, 0x9b, 0xf1, 0x95, 0x6f, 0x77, 0x4a, 0xf7, 0x4b, 0xeb, - 0xf5, 0x8d, 0xe6, 0x63, 0x66, 0xf7, 0x78, 0xe0, 0x53, 0xb3, 0x9d, 0x29, 0xa3, 0xe2, 0xb2, 0x5f, - 0xe8, 0x19, 0x34, 0xdc, 0x30, 0xc6, 0xc4, 0x1c, 0x85, 0x8e, 0x45, 0x70, 0xa7, 0xcc, 0xd4, 0x91, - 0x54, 0xdf, 0x3f, 0xc0, 0xe4, 0x4b, 0x56, 0xb3, 0x33, 0x65, 0xd4, 0x99, 0x26, 0x2f, 0xa2, 0xcf, - 0x00, 0x71, 0x43, 0x07, 0x7b, 0xc4, 0x92, 0xe6, 0xd3, 0xcc, 0x7c, 0x39, 0x6d, 0xde, 0xa7, 0xf5, - 0x0a, 0x43, 0x63, 0x46, 0x29, 0x59, 0xc2, 0x20, 0xc2, 0xc3, 0xe0, 0x1c, 0x77, 0x66, 0xc6, 0x19, - 0x18, 0xac, 0x46, 0x31, 0xe0, 0x45, 0xb4, 0x0f, 0x8b, 0x96, 0x4d, 0xdc, 0x73, 0x6c, 0x86, 0x51, - 0x70, 0xe2, 0x7a, 0x58, 0x92, 0x98, 0x65, 0x08, 0xab, 0x02, 0xa1, 0xc7, 0x74, 0xf6, 0xb9, 0x8a, - 0xe2, 0x31, 0x6f, 0x8d, 0x8b, 0x0b, 0x10, 0x05, 0xa7, 0xca, 0x64, 0x44, 0xc5, 0x2d, 0x8b, 0x28, - 0x38, 0xbe, 0x82, 0x05, 0x89, 0x18, 0x78, 0xae, 0x7d, 0x25, 0x29, 0xce, 0x31, 0xc0, 0x95, 0x2c, - 0x20, 0xd3, 0x50, 0x0c, 0x91, 0x35, 0x26, 0x1d, 0x87, 0x13, 0xfc, 0xaa, 0x13, 0xe1, 0x14, 0xbd, - 0x0c, 0x5c, 0xc2, 0xee, 0x2c, 0x88, 0x89, 0x89, 0x7d, 0x27, 0x0c, 0x5c, 0x5f, 0x05, 0x41, 0x2d, - 0x03, 0xb7, 0x13, 0xc4, 0x64, 0x5b, 0x68, 0x24, 0xec, 0xce, 0xc6, 0xa4, 0xe3, 0x70, 0x82, 0x1d, - 0x4c, 0x84, 0x4b, 0xd8, 0x9d, 0x8d, 0x49, 0xd1, 0xd7, 0xd0, 0xb9, 0x08, 0xa2, 0xd7, 0x5e, 0x60, - 0x39, 0x63, 0x0c, 0xeb, 0x0c, 0xf2, 0xae, 0x80, 0xfc, 0x4a, 0xa8, 0x8d, 0xb1, 0x5c, 0xba, 0x28, - 0xac, 0x29, 0x86, 0x16, 0x6c, 0x1b, 0xd7, 0x42, 0x2b, 0xc6, 0x63, 0xd0, 0x82, 0xf5, 0xc7, 0xd0, - 0xb4, 0x03, 0xff, 0xc4, 0x3d, 0x95, 0x54, 0x9b, 0x0c, 0x6f, 0x5e, 0xe0, 0x6d, 0xb1, 0x3a, 0x45, - 0xb0, 0x61, 0xa7, 0xca, 0xca, 0x81, 0x43, 0x4c, 0x2c, 0xc7, 0x4a, 0x46, 0x55, 0x6b, 0xcc, 0x81, - 0xaf, 0x84, 0x46, 0xf6, 0x7b, 0x64, 0xa5, 0xe8, 0x3d, 0x68, 0xc7, 0x34, 0x41, 0xf8, 0x36, 0x36, - 0xfd, 0xd1, 0xf0, 0x18, 0x47, 0x9d, 0xf6, 0xfd, 0xd2, 0xfa, 0x8c, 0xd1, 0x92, 0xe2, 0x5d, 0x26, - 0x45, 0x3d, 0xd0, 0xdc, 0xd0, 0x1a, 0x9a, 0x61, 0x10, 0x78, 0xb2, 0x4d, 0x8d, 0xb5, 0xb9, 0xa8, - 0x86, 0x61, 0xef, 0xd5, 0x7e, 0x10, 0x78, 0xaa, 0xbd, 0x16, 0x35, 0x48, 0x24, 0x59, 0x08, 0xe1, - 0xc9, 0x5b, 0x85, 0x10, 0xca, 0x83, 0x0a, 0x22, 0x17, 0x8d, 0xaa, 0xf7, 0x02, 0x06, 0x4d, 0xec, - 0x7d, 0x36, 0x7c, 0xb2, 0x52, 0x74, 0x00, 0x4b, 0x31, 0x8e, 0xce, 0x5d, 0x1b, 0x9b, 0x96, 0x6d, - 0x07, 0xa3, 0x24, 0x78, 0xe6, 0x19, 0xe0, 0x6d, 0x01, 0x78, 0xc0, 0x95, 0x7a, 0x5c, 0x47, 0x75, - 0x70, 0x21, 0x2e, 0x90, 0x17, 0x81, 0x0a, 0x96, 0x0b, 0xd7, 0x80, 0x2a, 0x9e, 0x39, 0x50, 0xc1, - 0x74, 0x0b, 0x34, 0xdf, 0x1a, 0xe2, 0x38, 0xb4, 0x6c, 0x95, 0xc3, 0x16, 0x19, 0xdc, 0x92, 0x80, - 0xdb, 0x95, 0xd5, 0x8a, 0x5e, 0xdb, 0xcf, 0x8a, 0xb2, 0x20, 0x82, 0xd3, 0x52, 0x31, 0x88, 0xa2, - 0x93, 0x80, 0x08, 0x26, 0xcf, 0xa0, 0x11, 0x05, 0x23, 0xa2, 0x58, 0x2c, 0x67, 0x72, 0xb1, 0x41, - 0xab, 0x92, 0xd9, 0x20, 0x4a, 0x8a, 0x89, 0xa1, 0x68, 0xb9, 0x33, 0x6e, 0x98, 0x24, 0xf1, 0x28, - 0x29, 0xa2, 0x2d, 0xa8, 0x9f, 0x13, 0x1c, 0xca, 0x06, 0x57, 0x98, 0xdd, 0x7d, 0x61, 0x77, 0xf4, - 0x3b, 0x2f, 0x7b, 0xbb, 0x87, 0x23, 0xdf, 0xc7, 0xde, 0xd8, 0xd0, 0x06, 0x6a, 0xa6, 0xfa, 0xce, - 0x41, 0x44, 0xe3, 0xab, 0x6f, 0x02, 0x51, 0x54, 0x18, 0x88, 0x60, 0xf2, 0x53, 0x58, 0xb9, 0x70, - 0x23, 0x7c, 0x3a, 0xb2, 0xa2, 0xf1, 0x7c, 0x73, 0x9b, 0x41, 0xae, 0xc9, 0xa4, 0x20, 0xf5, 0xc6, - 0x58, 0x2d, 0x5f, 0x14, 0x57, 0x4d, 0x40, 0x17, 0x84, 0xef, 0x5c, 0x8f, 0xae, 0xe8, 0x8e, 0xa3, - 0x0b, 0xee, 0x5f, 0x41, 0xe7, 0xd4, 0x0b, 0x8e, 0x2d, 0xcf, 0x3c, 0x3e, 0x0d, 0xcd, 0x6c, 0xfe, - 0xb9, 0xcb, 0xc0, 0xef, 0x08, 0xf0, 0xcf, 0x98, 0xda, 0x8b, 0xcf, 0xf6, 0x73, 0x89, 0x68, 0x91, - 0xdb, 0xbf, 0x38, 0x0d, 0xd3, 0x15, 0xe8, 0x47, 0xd0, 0xc4, 0xbe, 0x6d, 0x85, 0xf1, 0xc8, 0xb3, - 0x88, 0x1b, 0xf8, 0x9d, 0x35, 0x86, 0xb6, 0x20, 0xd0, 0xb6, 0xd3, 0x75, 0x3b, 0x53, 0x46, 0x56, - 0x19, 0xfd, 0x16, 0xb4, 0xe4, 0x68, 0x11, 0x64, 0xee, 0x65, 0xcc, 0xc5, 0x28, 0x51, 0x24, 0x9a, - 0x71, 0x5a, 0x90, 0x36, 0x17, 0x8e, 0xba, 0x5f, 0x64, 0xae, 0xdc, 0x23, 0xcd, 0x85, 0x53, 0x6c, - 0xb8, 0x53, 0xe0, 0xf2, 0xf3, 0xae, 0xe4, 0xf2, 0x4e, 0x26, 0x4c, 0xc6, 0xbc, 0x7e, 0xd4, 0x55, - 0xbc, 0x56, 0x2e, 0x26, 0x55, 0x4e, 0x6e, 0x44, 0x30, 0xd6, 0xdf, 0xd4, 0x88, 0x62, 0x5f, 0xd4, - 0x88, 0xe8, 0xc9, 0x21, 0x2c, 0x67, 0x33, 0x63, 0xd2, 0x89, 0x07, 0x99, 0xb4, 0x93, 0x4e, 0x8e, - 0x29, 0xfe, 0x0b, 0x67, 0x05, 0xf2, 0x42, 0x54, 0xc1, 0xfa, 0xdd, 0x6b, 0x50, 0x93, 0x64, 0x76, - 0x56, 0x20, 0x47, 0x3f, 0x81, 0x95, 0x1c, 0xea, 0x66, 0xc2, 0xf6, 0x61, 0x66, 0x6e, 0xcd, 0xe0, - 0x6e, 0xa6, 0xf8, 0x2e, 0x65, 0x90, 0x37, 0xcf, 0x25, 0xe3, 0x62, 0x6c, 0xc1, 0xf9, 0x7b, 0xd7, - 0x62, 0x27, 0xf3, 0x76, 0x1e, 0x9b, 0xd7, 0xbc, 0xa8, 0xc1, 0x5c, 0x68, 0x5d, 0xd1, 0x09, 0x5d, - 0xff, 0xd7, 0x59, 0x68, 0x7e, 0x1a, 0x05, 0xc3, 0x64, 0x3d, 0xbd, 0x0f, 0x8b, 0x61, 0x14, 0xd8, - 0x38, 0x8e, 0xcd, 0x98, 0x58, 0x64, 0x14, 0x67, 0xd7, 0xbb, 0x72, 0x61, 0xb8, 0xcf, 0x75, 0x0e, - 0x98, 0x4a, 0xb2, 0xd4, 0x0c, 0xc7, 0xc5, 0xe8, 0xf7, 0xe0, 0x76, 0x76, 0xad, 0x94, 0xc5, 0xe5, - 0x8b, 0xe0, 0x7b, 0x05, 0x4b, 0xa6, 0x1c, 0x78, 0xe7, 0x6c, 0x42, 0xdd, 0xc4, 0x16, 0x84, 0xbb, - 0x66, 0xdf, 0xd0, 0x82, 0x72, 0x58, 0x41, 0x0b, 0xe2, 0x53, 0x7b, 0x70, 0x6f, 0x7c, 0x15, 0x95, - 0xed, 0x07, 0x5f, 0x38, 0x3f, 0x98, 0xb0, 0x98, 0xca, 0xf5, 0xe5, 0xce, 0xc5, 0x35, 0xf5, 0xd7, - 0xb6, 0x26, 0xfa, 0x34, 0x77, 0x83, 0xd6, 0x54, 0xbf, 0x26, 0xb4, 0x26, 0xfa, 0x56, 0xb0, 0x76, - 0xaa, 0x16, 0xae, 0x9d, 0x8e, 0x20, 0xc9, 0xca, 0xb9, 0xce, 0xd7, 0x32, 0x99, 0x57, 0x8d, 0xfd, - 0x5c, 0xaf, 0x17, 0x2f, 0x8a, 0x2a, 0x50, 0x1f, 0x6e, 0x39, 0x32, 0xfe, 0x4c, 0xb9, 0x99, 0x83, - 0xcc, 0x84, 0xae, 0xe2, 0x53, 0xed, 0xea, 0xda, 0x4e, 0x56, 0x94, 0x8e, 0xea, 0x7f, 0x29, 0x43, - 0x23, 0x93, 0xdb, 0x9f, 0x41, 0x85, 0xcf, 0x14, 0x9d, 0xd2, 0xfd, 0xe9, 0x54, 0x2c, 0xa4, 0x95, - 0x44, 0x61, 0xdb, 0x27, 0xd1, 0x95, 0x21, 0xd4, 0xd1, 0xef, 0xc2, 0x42, 0x1c, 0x8c, 0x22, 0x1b, - 0x9b, 0x24, 0x30, 0x23, 0xeb, 0x42, 0x4c, 0x38, 0x9d, 0x32, 0x83, 0x79, 0x54, 0x04, 0x73, 0xc0, - 0xf4, 0x0f, 0x03, 0xc3, 0xba, 0x48, 0x23, 0xde, 0x8a, 0xf3, 0x72, 0xd4, 0x81, 0xb9, 0x21, 0x8e, - 0x63, 0xeb, 0x94, 0x0f, 0xae, 0x9a, 0x21, 0x8b, 0xab, 0xcf, 0xa1, 0x9e, 0xb2, 0x45, 0x1a, 0x4c, - 0xbf, 0xc6, 0x57, 0x6c, 0x7f, 0x5b, 0x33, 0xe8, 0x4f, 0xb4, 0x00, 0xb3, 0xe7, 0x96, 0x37, 0xe2, - 0x9b, 0xd8, 0x9a, 0xc1, 0x0b, 0x1f, 0x97, 0x7f, 0x58, 0x5a, 0x3d, 0x82, 0xa5, 0x62, 0x06, 0x69, - 0x94, 0x26, 0x47, 0xf9, 0x5e, 0x1a, 0xa5, 0xbe, 0xa1, 0xc9, 0x35, 0x8c, 0xb4, 0x4b, 0xe1, 0xea, - 0x7f, 0x55, 0x82, 0x5a, 0x42, 0x7d, 0x09, 0x2a, 0xbc, 0x3f, 0x82, 0x94, 0x28, 0xa1, 0x4d, 0xe5, - 0x68, 0xee, 0xa1, 0x3b, 0x79, 0xc8, 0x22, 0x2f, 0xff, 0x0a, 0xdd, 0xd5, 0xab, 0x50, 0xe1, 0xdf, - 0x5f, 0xff, 0x9b, 0x12, 0xd4, 0x53, 0x9b, 0x78, 0xd4, 0x82, 0xb2, 0xeb, 0x08, 0x90, 0xb2, 0xeb, - 0x70, 0x6f, 0xd3, 0x38, 0x8e, 0x19, 0x37, 0xe6, 0x6d, 0x56, 0x44, 0x4f, 0x60, 0x86, 0x5c, 0x85, - 0xfc, 0x23, 0xb4, 0x14, 0xe5, 0x14, 0x16, 0xff, 0x7d, 0x78, 0x15, 0x62, 0x83, 0x69, 0xea, 0x1f, - 0x40, 0x4d, 0x89, 0x50, 0x05, 0xca, 0x83, 0x7d, 0x6d, 0x0a, 0xb5, 0x69, 0xfb, 0x66, 0x6f, 0xb7, - 0x6f, 0xee, 0xef, 0x19, 0x87, 0x5a, 0x09, 0xcd, 0xc1, 0xf4, 0xee, 0xf6, 0xa1, 0x56, 0xd6, 0x43, - 0xd0, 0xf2, 0xe7, 0x03, 0x63, 0xf4, 0x1e, 0x40, 0xd3, 0x72, 0x1c, 0xec, 0x98, 0x59, 0x92, 0x0d, - 0x26, 0x7c, 0x25, 0x98, 0xbe, 0x07, 0x6d, 0x3e, 0xfe, 0x13, 0xb5, 0x69, 0xa6, 0xd6, 0x12, 0x62, - 0xa1, 0xa8, 0xdf, 0x15, 0xbe, 0x10, 0x43, 0x3c, 0xd7, 0x98, 0x6e, 0xc1, 0x7c, 0xc1, 0x59, 0x01, - 0xba, 0xaf, 0xd4, 0x92, 0x60, 0x10, 0x1a, 0x83, 0x3e, 0x63, 0xb9, 0x0e, 0x73, 0xe2, 0xbc, 0x40, - 0xc4, 0x4c, 0x2b, 0xab, 0x66, 0xc8, 0x6a, 0xfd, 0x59, 0xae, 0x09, 0xc1, 0xe4, 0x8d, 0x4d, 0xe8, - 0xf7, 0xa0, 0xa6, 0x04, 0x08, 0xc1, 0x0c, 0x5d, 0xb8, 0x0b, 0xea, 0xec, 0xb7, 0x1e, 0xc0, 0x9c, - 0x50, 0x40, 0x4f, 0xa0, 0xe9, 0xfa, 0xc7, 0xc1, 0xc8, 0x77, 0xcc, 0x68, 0xe4, 0xe1, 0x58, 0x0c, - 0xef, 0xba, 0x8c, 0xba, 0x91, 0x87, 0x8d, 0x86, 0xd0, 0xa0, 0x85, 0x18, 0x6d, 0x40, 0x2b, 0x18, - 0x91, 0xb4, 0x49, 0x79, 0xdc, 0xa4, 0x29, 0x55, 0x98, 0x8d, 0xfe, 0x53, 0x40, 0xe3, 0xc7, 0x16, - 0xe8, 0x5e, 0xaa, 0x27, 0x6d, 0xd9, 0x13, 0xa6, 0x20, 0x7c, 0xf5, 0x10, 0x2a, 0xfc, 0xe8, 0x42, - 0xb8, 0xaa, 0x99, 0x51, 0x32, 0x44, 0xa5, 0xfe, 0x34, 0x8b, 0x2e, 0xfc, 0xf4, 0x26, 0x74, 0x7d, - 0x03, 0xaa, 0xb2, 0x4c, 0xbd, 0x44, 0x5c, 0x1c, 0x49, 0x2f, 0xd1, 0xdf, 0xca, 0x73, 0xe5, 0x94, - 0xe7, 0xfe, 0xbb, 0x04, 0x15, 0x6e, 0xf4, 0xeb, 0xf1, 0x1c, 0xba, 0x03, 0xb5, 0x91, 0x4f, 0x22, - 0xcb, 0x7e, 0x8d, 0x1d, 0x36, 0xbc, 0xaa, 0x46, 0x22, 0x40, 0x2b, 0x50, 0x0d, 0x23, 0x6c, 0x3a, - 0xbe, 0x45, 0xd8, 0x2a, 0xa0, 0x4a, 0xa3, 0x07, 0xf7, 0x7d, 0x8b, 0x50, 0x43, 0xb5, 0x61, 0x63, - 0xf3, 0x77, 0xcd, 0x48, 0x04, 0xe8, 0xfb, 0x70, 0x2b, 0x88, 0xdc, 0x53, 0xd7, 0xb7, 0x3c, 0x33, - 0xc6, 0x1e, 0xb6, 0x49, 0x10, 0xb1, 0xf9, 0xb7, 0x66, 0x68, 0xb2, 0xe2, 0x40, 0xc8, 0xf5, 0xbf, - 0xd3, 0x60, 0x86, 0xb2, 0xa1, 0x39, 0xcb, 0xb2, 0xd9, 0xca, 0x5e, 0xe4, 0x2c, 0x5e, 0x42, 0x1f, - 0x02, 0xb8, 0xa1, 0x79, 0x8e, 0xa3, 0x98, 0xd6, 0x95, 0x59, 0x12, 0xd0, 0x54, 0x12, 0x38, 0xe2, - 0x72, 0xa3, 0xe6, 0x86, 0xe2, 0x27, 0xfa, 0x3e, 0xe5, 0x1d, 0x90, 0xc0, 0x0e, 0x3c, 0xb1, 0x2a, - 0x6a, 0x27, 0x91, 0xcc, 0xc4, 0x86, 0x52, 0x40, 0xcb, 0x30, 0x17, 0x47, 0xb6, 0xe9, 0x63, 0xda, - 0xc7, 0x69, 0x96, 0x2a, 0x23, 0x7b, 0x17, 0x13, 0xf4, 0x01, 0xd4, 0x68, 0x45, 0x18, 0x44, 0x24, - 0xee, 0xcc, 0x32, 0x57, 0xaa, 0x01, 0x11, 0x44, 0xc4, 0xb0, 0xfc, 0x53, 0x6c, 0x54, 0xe3, 0xc8, - 0xa6, 0xa5, 0x98, 0xe2, 0x38, 0x31, 0x61, 0x38, 0x15, 0x8e, 0xe3, 0xc4, 0x44, 0xe0, 0xd0, 0x0a, - 0x8e, 0x33, 0x37, 0x09, 0xc7, 0x89, 0x09, 0xc7, 0xb9, 0x0b, 0x35, 0xd7, 0x1e, 0x86, 0x26, 0xcb, - 0x78, 0x74, 0x9e, 0x9f, 0xdd, 0x99, 0x32, 0xaa, 0x54, 0xc4, 0x92, 0xd9, 0x27, 0xd0, 0x52, 0xd5, - 0xa6, 0x1d, 0x38, 0x72, 0x6a, 0x97, 0x13, 0xf1, 0x40, 0x28, 0xf6, 0x7c, 0x67, 0x2b, 0x70, 0xd8, - 0xb9, 0x8e, 0xb4, 0xa5, 0x65, 0xf4, 0x00, 0x5a, 0xb4, 0x57, 0x6e, 0x68, 0xc6, 0x98, 0x98, 0xae, - 0x13, 0x77, 0x80, 0xb1, 0xad, 0xc7, 0x91, 0x3d, 0x08, 0x0f, 0x30, 0x19, 0x38, 0x31, 0x55, 0xa2, - 0x94, 0x53, 0x4a, 0x75, 0xae, 0xe4, 0xc4, 0x44, 0x29, 0x3d, 0x83, 0x15, 0xe6, 0x38, 0x6b, 0x88, - 0x1d, 0xd6, 0xbb, 0xb4, 0x7e, 0x83, 0xe9, 0x2f, 0x50, 0x57, 0xd2, 0x7a, 0xda, 0xb5, 0xb4, 0x21, - 0xf3, 0x54, 0xa1, 0x61, 0x93, 0x1b, 0x52, 0xdf, 0x8d, 0x19, 0xfe, 0x00, 0xe6, 0x05, 0x2d, 0x66, - 0x25, 0x4d, 0xda, 0xcc, 0xa4, 0xcd, 0xb8, 0x51, 0x7d, 0xa1, 0xbd, 0x01, 0x0d, 0x3f, 0x20, 0xa6, - 0x8a, 0x84, 0x93, 0xe2, 0x48, 0xa8, 0xfb, 0x01, 0x91, 0x05, 0xb4, 0x06, 0xb4, 0x68, 0xca, 0x80, - 0x38, 0x65, 0xc8, 0x35, 0x3f, 0x20, 0x07, 0x3c, 0x26, 0x36, 0xa1, 0x29, 0xeb, 0xf9, 0xf7, 0x3c, - 0x9b, 0xf0, 0x3d, 0xeb, 0xdc, 0x86, 0x7f, 0x52, 0x81, 0x2a, 0xc3, 0xc3, 0x55, 0xa8, 0x7d, 0x1e, - 0x21, 0x02, 0x35, 0x89, 0x92, 0xdf, 0xbf, 0x06, 0xb5, 0x2f, 0x03, 0xe5, 0x5d, 0x6e, 0x95, 0x04, - 0xcb, 0x6b, 0x16, 0x2c, 0x25, 0xa6, 0x25, 0xc3, 0x00, 0x6d, 0x03, 0xca, 0x68, 0xf1, 0x98, 0xf1, - 0xae, 0x8d, 0x99, 0x92, 0xd1, 0x4e, 0x41, 0xb0, 0xb0, 0x79, 0xc4, 0x61, 0x72, 0xa1, 0x33, 0xe4, - 0x73, 0x1b, 0xef, 0xab, 0xfa, 0x4c, 0x42, 0x37, 0x17, 0x41, 0xbe, 0xd2, 0xed, 0xa7, 0x82, 0xe8, - 0x13, 0xb8, 0xab, 0x1c, 0x5e, 0x18, 0x0f, 0x21, 0x33, 0x5b, 0x16, 0x9f, 0x60, 0x2c, 0x24, 0x84, - 0xfd, 0xe4, 0x78, 0xfa, 0x46, 0xd9, 0xf7, 0x8b, 0x42, 0x6a, 0x03, 0x16, 0x93, 0x4c, 0x15, 0xd9, - 0x49, 0xb6, 0x8a, 0x58, 0x0a, 0x9a, 0x57, 0xd9, 0x2a, 0xb2, 0x65, 0xc2, 0xca, 0xd8, 0xd0, 0x86, - 0x95, 0x4d, 0x9c, 0xb5, 0xe9, 0xc7, 0x44, 0xd9, 0x6c, 0xc3, 0xbd, 0x4c, 0x3b, 0xc9, 0xf9, 0x98, - 0xb2, 0x26, 0xcc, 0xfa, 0x4e, 0xaa, 0x45, 0x75, 0x4a, 0x56, 0x08, 0x23, 0xfb, 0x9c, 0x83, 0x19, - 0x65, 0x61, 0x44, 0xaf, 0xb3, 0x30, 0xcf, 0x61, 0x45, 0xc1, 0x48, 0xf7, 0x2b, 0x80, 0x73, 0x06, - 0xb0, 0x24, 0x15, 0x76, 0x99, 0xe7, 0x27, 0x9a, 0x66, 0x1c, 0x70, 0x31, 0x66, 0x9a, 0xf6, 0xc1, - 0x97, 0x3c, 0x61, 0xe4, 0x0f, 0x2d, 0x87, 0x16, 0xb1, 0xcf, 0x3a, 0x97, 0x99, 0xdd, 0x6b, 0xf6, - 0xcc, 0xf2, 0x15, 0xd5, 0x30, 0x96, 0x62, 0x4a, 0x63, 0x4c, 0x4e, 0x61, 0x39, 0x89, 0x22, 0xd8, - 0xab, 0x37, 0xc3, 0x3a, 0x94, 0xe2, 0x38, 0xec, 0x87, 0x00, 0x67, 0x84, 0x84, 0x02, 0xe7, 0x67, - 0x99, 0x05, 0xd1, 0xce, 0xe1, 0xe1, 0x3e, 0xb7, 0xae, 0x51, 0x1d, 0x69, 0x50, 0x95, 0x87, 0x01, - 0x9d, 0x3f, 0xc8, 0x1c, 0xb4, 0xd3, 0xd9, 0x4d, 0x9d, 0x08, 0x2b, 0x25, 0xf4, 0x1b, 0xb0, 0x90, - 0x8b, 0x23, 0xc6, 0xa2, 0xf3, 0x47, 0x7c, 0xfa, 0x43, 0x99, 0x38, 0x62, 0x55, 0xa8, 0x0f, 0x6b, - 0x45, 0x26, 0x49, 0x1c, 0x74, 0xfe, 0x98, 0x1b, 0xdf, 0x1e, 0x37, 0x56, 0x61, 0x90, 0x69, 0x38, - 0xf5, 0x45, 0x3a, 0x3f, 0xcf, 0x35, 0x7c, 0xa0, 0x1c, 0x9e, 0x69, 0x38, 0xfd, 0x11, 0x93, 0x86, - 0xff, 0x24, 0xd7, 0x70, 0x62, 0x9c, 0x34, 0xdc, 0x81, 0x39, 0xba, 0x32, 0x31, 0x5d, 0xa7, 0xf3, - 0x4b, 0x31, 0xc7, 0xd3, 0xf2, 0xc0, 0x79, 0x51, 0x81, 0x19, 0x9a, 0xa2, 0x5e, 0x00, 0x54, 0x65, - 0xba, 0xfa, 0xbc, 0x52, 0xfd, 0x45, 0x49, 0xfb, 0x65, 0xc9, 0x00, 0x2f, 0x38, 0x35, 0xc3, 0x08, - 0x9f, 0xb8, 0x97, 0xfa, 0x67, 0x30, 0x5f, 0xf4, 0xb1, 0x56, 0xa1, 0xaa, 0x82, 0x90, 0x03, 0xab, - 0x32, 0xdd, 0x9b, 0x30, 0x96, 0x62, 0xc1, 0xce, 0x0b, 0xfa, 0xdf, 0x96, 0xa0, 0xa6, 0x3e, 0x23, - 0xdf, 0x7b, 0x90, 0xb3, 0xc0, 0xe1, 0xeb, 0x2c, 0xb6, 0xf7, 0x60, 0x45, 0xf4, 0x04, 0x66, 0x43, - 0x8b, 0x9c, 0xc9, 0xc5, 0xd4, 0x6a, 0x3e, 0x02, 0x1e, 0xef, 0x5b, 0xe4, 0x8c, 0xc7, 0x02, 0x57, - 0x5c, 0xfd, 0x02, 0x6a, 0x4a, 0x86, 0x96, 0x60, 0x16, 0x5f, 0x5a, 0x36, 0xe1, 0xac, 0x76, 0xa6, - 0x0c, 0x5e, 0x44, 0x1d, 0xa8, 0xf0, 0x1e, 0xf1, 0xf5, 0xdf, 0xce, 0x94, 0x21, 0xca, 0x2f, 0x1a, - 0x00, 0x14, 0x87, 0xc7, 0x9d, 0xfe, 0xd7, 0x25, 0x68, 0xa4, 0xc3, 0x07, 0x7d, 0x0a, 0x75, 0xcb, - 0xf7, 0x03, 0xc2, 0x4e, 0x35, 0xe5, 0xaa, 0xf0, 0xdd, 0x82, 0x40, 0x7b, 0xdc, 0x4b, 0xd4, 0xf8, - 0x6e, 0x2e, 0x6d, 0xb8, 0xfa, 0x09, 0x68, 0x79, 0x85, 0xb7, 0xda, 0xd7, 0x3d, 0x87, 0x76, 0x6e, - 0xda, 0x60, 0xab, 0x5c, 0x3a, 0x0f, 0x51, 0xfb, 0x59, 0xbe, 0x11, 0xa3, 0x32, 0x36, 0xe1, 0x94, - 0xb9, 0x8c, 0xfe, 0xd6, 0x5f, 0x42, 0x55, 0x4d, 0xb8, 0x1d, 0xa8, 0x88, 0x23, 0x8d, 0x92, 0x58, - 0xea, 0x88, 0x32, 0x5a, 0x48, 0xaf, 0x8f, 0x77, 0xa6, 0xf8, 0x0a, 0xf9, 0x85, 0x06, 0x2d, 0x5e, - 0x6f, 0x06, 0x11, 0x0b, 0x3e, 0xfd, 0x29, 0xd4, 0xd4, 0x04, 0x49, 0xf9, 0x9e, 0xb8, 0x51, 0x4c, - 0x04, 0x07, 0x5e, 0xa0, 0x24, 0x3c, 0x2b, 0x26, 0x92, 0x04, 0xfd, 0xad, 0xff, 0x45, 0x09, 0x50, - 0xfe, 0x54, 0x66, 0xd0, 0xa7, 0x1b, 0xb8, 0x20, 0xb2, 0xcf, 0x70, 0x4c, 0x22, 0x8b, 0x04, 0x11, - 0x8d, 0x54, 0xde, 0xf5, 0x56, 0x5a, 0x3c, 0x70, 0xd0, 0x3d, 0xa8, 0xab, 0x23, 0x20, 0xd7, 0x11, - 0xe7, 0x03, 0x20, 0x45, 0x5c, 0x41, 0x1d, 0x0d, 0xb9, 0x0e, 0x5b, 0x3f, 0xd7, 0x0c, 0x90, 0xa2, - 0x81, 0xf3, 0xf9, 0x4c, 0xb5, 0xa4, 0x95, 0x8d, 0xea, 0x59, 0x10, 0x13, 0xd6, 0x91, 0x4b, 0x58, - 0x2a, 0xbe, 0x3c, 0x44, 0xef, 0xa7, 0xf6, 0x1a, 0x2b, 0x13, 0x4e, 0x94, 0xc4, 0x9e, 0xe6, 0x23, - 0xa8, 0xca, 0x26, 0xc4, 0xb1, 0xda, 0xf2, 0xa4, 0xdb, 0x43, 0xa5, 0xa8, 0xff, 0xcf, 0x34, 0x68, - 0xf9, 0x6a, 0xea, 0xca, 0x98, 0x58, 0x44, 0x6e, 0xed, 0x78, 0xa1, 0x68, 0xd7, 0x42, 0xc3, 0x66, - 0x68, 0xd9, 0xc2, 0x05, 0xf4, 0x27, 0xed, 0xbb, 0xbc, 0xb5, 0xa6, 0x73, 0x30, 0x5f, 0x57, 0x83, - 0x10, 0xd1, 0x69, 0xf7, 0x36, 0xd4, 0xdc, 0xf0, 0x7c, 0x93, 0x2e, 0x87, 0xf8, 0xda, 0xba, 0x66, - 0x54, 0xa9, 0x60, 0x17, 0x13, 0x59, 0xd9, 0xe5, 0x95, 0x15, 0x55, 0xd9, 0x65, 0x95, 0x0f, 0x61, - 0x96, 0x6e, 0x9f, 0xe4, 0x4a, 0x5a, 0x2e, 0xe7, 0x0e, 0x5d, 0x1c, 0x0d, 0xfc, 0x93, 0xc0, 0xe0, - 0xb5, 0xe8, 0x7d, 0xa8, 0xf2, 0x06, 0x2c, 0xd2, 0xa9, 0x32, 0xcd, 0x96, 0xba, 0x7a, 0x22, 0x4c, - 0x71, 0x8e, 0xb5, 0x67, 0x11, 0xa1, 0xda, 0x65, 0xaa, 0xb5, 0x89, 0xaa, 0x5d, 0xaa, 0xda, 0x83, - 0xbb, 0x96, 0xe7, 0x05, 0x17, 0x66, 0x1c, 0x06, 0xc1, 0x09, 0x76, 0x4c, 0x71, 0xf6, 0xc4, 0x87, - 0x2e, 0x96, 0x6b, 0xe9, 0x55, 0xa6, 0x74, 0xc0, 0x75, 0xf8, 0x61, 0xcf, 0xbe, 0xd0, 0x40, 0x9f, - 0x67, 0xc7, 0x6f, 0x9d, 0x35, 0xb8, 0x3e, 0xe1, 0x1b, 0xfd, 0x3f, 0x8f, 0xe1, 0xad, 0xf1, 0x88, - 0x13, 0xbb, 0xdb, 0x9b, 0x47, 0x9c, 0xde, 0x83, 0x56, 0xfa, 0xc4, 0x76, 0xd0, 0xcf, 0x47, 0x7e, - 0xf9, 0x8d, 0x91, 0xef, 0x01, 0x1a, 0xbf, 0xd8, 0x47, 0x0f, 0x53, 0x1c, 0x16, 0x0b, 0xce, 0x86, - 0x45, 0xc4, 0x7f, 0x98, 0x8a, 0xf8, 0xe9, 0xcc, 0xb4, 0x9b, 0xb9, 0xdd, 0x4f, 0xa2, 0xfd, 0xbf, - 0xca, 0xd0, 0x48, 0x57, 0x15, 0x9d, 0x61, 0xe4, 0x23, 0xb8, 0x3c, 0x16, 0xc1, 0x2a, 0x0e, 0xa7, - 0xaf, 0x8d, 0xc3, 0xc7, 0x30, 0x8f, 0x2f, 0x43, 0x6c, 0x13, 0xec, 0x98, 0x2c, 0x20, 0x2d, 0xc7, - 0x89, 0xe4, 0x88, 0xb8, 0x25, 0xab, 0x06, 0xe1, 0xf9, 0x66, 0x8f, 0x56, 0xe4, 0xf5, 0xbb, 0x42, - 0x7f, 0x76, 0x4c, 0xbf, 0xcb, 0xf5, 0x7f, 0x08, 0x6d, 0xb5, 0x5f, 0x37, 0x39, 0xa1, 0x4a, 0x31, - 0xa1, 0x96, 0xd2, 0x3b, 0x64, 0xcc, 0x9e, 0x42, 0x4b, 0x6e, 0xee, 0xcd, 0x6b, 0x47, 0x54, 0x43, - 0xec, 0xf9, 0xb9, 0xd9, 0x26, 0x34, 0x4f, 0x82, 0xe8, 0xc2, 0x8a, 0x64, 0x73, 0xd5, 0x09, 0x56, - 0x42, 0x8b, 0x59, 0xe9, 0xbf, 0x99, 0xfd, 0xc2, 0x22, 0xca, 0x6e, 0xf6, 0x85, 0xf5, 0x08, 0xaa, - 0x12, 0xb6, 0xf0, 0x5b, 0xbd, 0x0f, 0x9a, 0xeb, 0x9f, 0x46, 0x38, 0x8e, 0xf9, 0x53, 0x14, 0x57, - 0xcd, 0xf5, 0x6d, 0x21, 0xdf, 0x17, 0x62, 0x9a, 0xde, 0x71, 0x4e, 0x53, 0x9c, 0xcf, 0xe1, 0x8c, - 0xa2, 0xfe, 0x0c, 0xe6, 0xc4, 0xe8, 0x47, 0x8b, 0x50, 0xc1, 0x97, 0x74, 0x4f, 0x21, 0x33, 0x21, - 0xbe, 0x24, 0x83, 0x90, 0x8a, 0x59, 0x80, 0x87, 0x72, 0x5c, 0x51, 0xc2, 0xa1, 0x6e, 0xc0, 0x7c, - 0xc1, 0xd5, 0x0b, 0x7a, 0x00, 0x4d, 0x37, 0x0e, 0x4c, 0xe2, 0x0e, 0x71, 0x4c, 0xac, 0xa1, 0xc4, - 0x6a, 0xb8, 0x71, 0x70, 0x28, 0x65, 0x68, 0x09, 0x2a, 0xa3, 0x90, 0xaa, 0x30, 0xc8, 0x92, 0x21, - 0x4a, 0x7a, 0x08, 0x9d, 0x49, 0xd7, 0x2e, 0x37, 0x1d, 0x25, 0x1f, 0x40, 0x85, 0x5f, 0x08, 0x88, - 0xb3, 0xae, 0x45, 0x75, 0x6b, 0x9a, 0xb9, 0x70, 0x10, 0x4a, 0xfa, 0x3a, 0xb4, 0xb2, 0x35, 0xec, - 0x40, 0x99, 0x03, 0xc8, 0x03, 0x65, 0xae, 0xd9, 0x2b, 0xe2, 0xf6, 0x76, 0xdf, 0xf7, 0x12, 0xee, - 0x5c, 0x77, 0x1b, 0xf3, 0x36, 0xd3, 0xdf, 0x5b, 0x76, 0x73, 0x30, 0xa9, 0xe5, 0xb7, 0x4f, 0x83, - 0xa7, 0xb0, 0x58, 0x78, 0xab, 0x82, 0xee, 0x02, 0x84, 0xa3, 0x63, 0xcf, 0xb5, 0xcd, 0x24, 0x2f, - 0xd7, 0xb8, 0xe4, 0x0b, 0x7c, 0xf5, 0xd6, 0x87, 0x5b, 0xfa, 0x2d, 0x68, 0xe7, 0x2e, 0x5b, 0xf4, - 0x3f, 0x2d, 0xc3, 0x52, 0xf1, 0x05, 0x26, 0x5d, 0x18, 0xcb, 0x34, 0x2b, 0x17, 0xc6, 0xb2, 0xac, - 0x26, 0x61, 0x9a, 0x62, 0x44, 0x10, 0xb3, 0x49, 0x93, 0x66, 0x16, 0x35, 0x09, 0xb3, 0xca, 0x69, - 0x55, 0xc9, 0xd2, 0x0e, 0x45, 0xb5, 0x62, 0xb1, 0x6e, 0xe3, 0x0b, 0x1b, 0x55, 0x46, 0x3d, 0xa8, - 0x78, 0xd6, 0x31, 0xf6, 0xe4, 0x99, 0xd9, 0xfb, 0xd7, 0xde, 0xb0, 0x3e, 0x7e, 0xc9, 0x74, 0xc5, - 0x75, 0x03, 0x37, 0x5c, 0x7d, 0x0e, 0xf5, 0x94, 0xf8, 0xad, 0xa6, 0xb4, 0xdf, 0x1e, 0xf7, 0x84, - 0xf8, 0x96, 0xff, 0x57, 0x4f, 0xe8, 0xaf, 0x78, 0xee, 0xca, 0x3d, 0x68, 0xfa, 0xae, 0xe0, 0x7e, - 0x55, 0x76, 0x7b, 0xb0, 0x50, 0x74, 0xd3, 0x7e, 0x03, 0xc0, 0x6e, 0x1e, 0xb0, 0x5b, 0x0c, 0x78, - 0x63, 0x86, 0x13, 0x00, 0xb7, 0xa1, 0x95, 0x7d, 0xb2, 0x55, 0x70, 0xb5, 0x32, 0x13, 0x06, 0x81, - 0x27, 0xc6, 0x6c, 0x3b, 0xff, 0x48, 0x8b, 0x55, 0xea, 0xf7, 0x13, 0x98, 0x09, 0x97, 0x26, 0x3f, - 0x83, 0xaa, 0xd4, 0x60, 0xfb, 0x0e, 0xd7, 0x51, 0x27, 0xee, 0xf4, 0x37, 0x5a, 0x03, 0x18, 0x5a, - 0xf1, 0x37, 0x23, 0x1c, 0x59, 0x62, 0x47, 0x52, 0x35, 0x52, 0x12, 0xde, 0x0b, 0x37, 0x34, 0x87, - 0x74, 0xc3, 0xa2, 0x42, 0xde, 0x0d, 0x5f, 0xd1, 0xcd, 0xcd, 0x5d, 0x80, 0xf3, 0x4b, 0xcf, 0xf2, - 0x79, 0x2d, 0x0f, 0xfa, 0x1a, 0x93, 0xd0, 0x6a, 0xfd, 0x0f, 0x4b, 0xd0, 0xcc, 0xbc, 0x40, 0x41, - 0xef, 0x40, 0x83, 0xa1, 0x61, 0xdf, 0x3a, 0xf6, 0x30, 0xe7, 0x59, 0x35, 0xea, 0x54, 0xb6, 0xcd, - 0x45, 0x74, 0x52, 0xe0, 0x98, 0x52, 0x87, 0x73, 0x6a, 0x30, 0xa1, 0x54, 0x5a, 0x07, 0x2d, 0xa3, - 0x64, 0x9e, 0x77, 0xc5, 0x49, 0x7d, 0x2b, 0xad, 0x77, 0xd4, 0xd5, 0xff, 0xa1, 0x04, 0x0b, 0x45, - 0x2f, 0xc8, 0xd0, 0x7b, 0xa9, 0x34, 0xb6, 0x5c, 0x78, 0x14, 0x22, 0xd2, 0xe7, 0x8f, 0xd5, 0xd8, - 0xe5, 0xbb, 0xdd, 0xf7, 0xae, 0x79, 0x97, 0xf6, 0x5d, 0x8f, 0xdc, 0x1f, 0xe7, 0xc9, 0xab, 0xdb, - 0xef, 0x9b, 0x91, 0xd7, 0xfb, 0xa0, 0xe5, 0xe5, 0xd9, 0x6b, 0x8a, 0x52, 0xfe, 0x9a, 0xa2, 0xe8, - 0x0a, 0xe6, 0xef, 0x4b, 0xd0, 0xce, 0x3d, 0x71, 0x43, 0x7a, 0x8a, 0x02, 0xca, 0xbf, 0x60, 0x13, - 0xae, 0xfb, 0x38, 0xe7, 0x3a, 0xbd, 0xf8, 0xb9, 0xdc, 0x77, 0xed, 0xb5, 0xa7, 0x29, 0xb6, 0xc2, - 0x61, 0x37, 0x60, 0xab, 0xbf, 0x03, 0xf5, 0x94, 0xa8, 0xf0, 0x16, 0xef, 0x10, 0x80, 0xbf, 0x54, - 0x3b, 0x14, 0xfb, 0x78, 0x1a, 0xb9, 0x22, 0x8a, 0xd9, 0x6f, 0xc6, 0x8a, 0x46, 0xa0, 0x08, 0x5b, - 0x5e, 0xa0, 0x2e, 0x57, 0xaf, 0x08, 0xe4, 0x95, 0x92, 0x12, 0xe8, 0xff, 0x56, 0x86, 0x7a, 0xea, - 0xed, 0x1e, 0x7a, 0x37, 0x75, 0x66, 0x90, 0x4c, 0x7c, 0x4c, 0x23, 0xb9, 0xce, 0x45, 0x1f, 0xd1, - 0xb1, 0xc4, 0xdf, 0x73, 0x32, 0x6d, 0x3e, 0x4d, 0xde, 0x52, 0x89, 0x82, 0x0e, 0x79, 0xa6, 0x0e, - 0x6e, 0x28, 0x7f, 0x53, 0x37, 0x3a, 0x31, 0x91, 0xdb, 0x52, 0x27, 0x26, 0x48, 0x87, 0x26, 0x3b, - 0x34, 0x0d, 0x1c, 0x7e, 0x70, 0x25, 0x86, 0x71, 0xdd, 0x89, 0xc9, 0x6e, 0xe0, 0xb0, 0x73, 0x2a, - 0xb4, 0x06, 0x75, 0xa5, 0xe3, 0x86, 0xf2, 0x6a, 0x4b, 0x68, 0x0c, 0x42, 0xba, 0x31, 0x88, 0xad, - 0x21, 0x36, 0xe3, 0xd1, 0xb1, 0x8f, 0x09, 0x7b, 0xe6, 0x51, 0x35, 0x80, 0x8a, 0x0e, 0x98, 0x84, - 0x8e, 0x7b, 0xba, 0xa4, 0x0e, 0x46, 0xe4, 0x34, 0x70, 0xfd, 0x53, 0x76, 0x85, 0x53, 0x35, 0xea, - 0xbe, 0x45, 0xf6, 0x84, 0x08, 0x3d, 0x84, 0x96, 0x17, 0xd8, 0x96, 0x67, 0xca, 0xe3, 0x02, 0x76, - 0x87, 0x53, 0x35, 0x9a, 0x4c, 0x2a, 0x17, 0x18, 0x68, 0x03, 0xea, 0x84, 0x7d, 0x01, 0xde, 0x69, - 0xfe, 0xe0, 0x42, 0x76, 0x3a, 0xf9, 0x36, 0x06, 0x10, 0xf5, 0x5b, 0xbf, 0x27, 0xdc, 0x2b, 0x62, - 0x41, 0xf8, 0xa0, 0xac, 0x7c, 0xa0, 0xff, 0x67, 0x09, 0x56, 0x26, 0xbe, 0x65, 0x64, 0x81, 0x40, - 0xf3, 0x9b, 0x0c, 0x04, 0x9a, 0xf9, 0xc4, 0xf6, 0xbe, 0x9c, 0x6c, 0xef, 0x33, 0x13, 0xd2, 0x74, - 0x6e, 0xe1, 0xb0, 0x0e, 0x5a, 0x68, 0x45, 0xd8, 0x27, 0xa6, 0x83, 0xd9, 0x11, 0xa1, 0x1b, 0x0a, - 0x3f, 0xb7, 0xb8, 0xbc, 0xcf, 0xc4, 0x7c, 0x05, 0x3d, 0xb4, 0x6c, 0x9a, 0xcf, 0xb8, 0x97, 0x67, - 0x87, 0x96, 0x7d, 0xd4, 0xcd, 0x4e, 0x26, 0x95, 0xdc, 0xca, 0xe3, 0x07, 0x80, 0xf2, 0xe8, 0xe7, - 0x5d, 0xf6, 0x15, 0x6a, 0x86, 0x96, 0xc5, 0x3f, 0xef, 0xea, 0x1f, 0x16, 0xf6, 0x55, 0xf8, 0xa6, - 0xa0, 0xaf, 0xfa, 0xcf, 0x4b, 0xb0, 0x3c, 0xe1, 0x45, 0xe5, 0xb5, 0x13, 0x60, 0x76, 0x91, 0x57, - 0xce, 0x2f, 0xf2, 0x1e, 0xc3, 0xbc, 0xeb, 0x13, 0x1c, 0x9d, 0x58, 0x9c, 0x71, 0xc6, 0x75, 0xb7, - 0x54, 0x95, 0xdc, 0x06, 0xea, 0x4f, 0x0b, 0x58, 0xbc, 0x79, 0x1a, 0xd6, 0xff, 0xbc, 0x04, 0x2b, - 0x13, 0xdf, 0x0e, 0x5e, 0xcb, 0x5f, 0x87, 0x66, 0xc2, 0x9f, 0x7e, 0x11, 0xde, 0x85, 0xba, 0xea, - 0xc2, 0x51, 0x77, 0xac, 0x13, 0xdd, 0x89, 0x9d, 0xe0, 0xf3, 0xfe, 0xb3, 0x42, 0x32, 0x37, 0xe8, - 0xc6, 0x3f, 0x96, 0x60, 0xb1, 0xf0, 0x6d, 0x28, 0xda, 0x80, 0x45, 0x79, 0xf0, 0x6c, 0x7b, 0xa3, - 0x98, 0xe0, 0xc8, 0xa4, 0x33, 0xbb, 0x3c, 0xb4, 0x9d, 0x17, 0x95, 0x5b, 0xbc, 0x6e, 0x8b, 0x56, - 0xa1, 0xcd, 0xe4, 0x99, 0x34, 0xbe, 0x24, 0x38, 0xf2, 0x2d, 0x4f, 0x18, 0x95, 0xc5, 0x1d, 0x25, - 0xaf, 0xdd, 0x16, 0x95, 0xdc, 0xea, 0x47, 0xb0, 0x2a, 0xad, 0xe8, 0x58, 0x3c, 0xb6, 0x3c, 0xcb, - 0xb7, 0x55, 0x73, 0x7c, 0xcf, 0xd8, 0x11, 0x1a, 0x2f, 0x53, 0x0a, 0xcc, 0x5a, 0xff, 0x1a, 0xea, - 0x62, 0x2a, 0xda, 0x0f, 0x22, 0x42, 0x3b, 0x2b, 0x0f, 0x3c, 0x65, 0x67, 0xd5, 0x01, 0x28, 0x82, - 0x19, 0xaa, 0x23, 0xcf, 0x26, 0xa5, 0x3e, 0xcd, 0x36, 0x4c, 0x3e, 0xcd, 0xe4, 0xaa, 0x4c, 0xc7, - 0x6f, 0x33, 0xf3, 0x56, 0xb5, 0x70, 0x4b, 0x9c, 0x99, 0xf7, 0xca, 0x05, 0xf3, 0x9e, 0x7a, 0x4f, - 0x53, 0x13, 0x29, 0xf6, 0x2e, 0x80, 0x74, 0xa9, 0x1a, 0xb0, 0x35, 0x21, 0x19, 0x84, 0x74, 0xe3, - 0x9c, 0xf1, 0x83, 0x4a, 0x8d, 0xad, 0xb4, 0x78, 0x10, 0xd2, 0xf4, 0xa7, 0xdc, 0xec, 0x86, 0xf2, - 0xfc, 0xae, 0x2e, 0x65, 0x83, 0x30, 0x46, 0xeb, 0x30, 0x9b, 0xbe, 0x0c, 0x47, 0xd9, 0x49, 0x9d, - 0x1d, 0xe6, 0x72, 0x05, 0xbd, 0xa7, 0xfa, 0x9a, 0x1a, 0xb3, 0x6f, 0xd5, 0xd7, 0x47, 0xeb, 0x50, - 0x53, 0xdb, 0x28, 0x34, 0x07, 0xd3, 0xbd, 0xdd, 0xaf, 0xb5, 0x29, 0x54, 0x85, 0x99, 0xc1, 0xfe, - 0xd1, 0xa6, 0x36, 0x23, 0x7e, 0x75, 0xb5, 0xca, 0xa3, 0x3f, 0x2b, 0x41, 0x4d, 0x4d, 0x3c, 0xa8, - 0x09, 0xb5, 0xad, 0x41, 0xdf, 0x30, 0x07, 0xbb, 0x9f, 0xee, 0x69, 0x53, 0x68, 0x1e, 0xda, 0xc6, - 0xf6, 0xab, 0xbd, 0xc3, 0x6d, 0xf3, 0xab, 0x3d, 0xe3, 0x8b, 0x97, 0x7b, 0xbd, 0xbe, 0x56, 0x42, - 0x6d, 0xa8, 0x0b, 0xe1, 0xce, 0xde, 0xc1, 0xa1, 0x56, 0x46, 0x08, 0x5a, 0x2f, 0xf7, 0xb6, 0x7a, - 0x2f, 0x13, 0xa5, 0x69, 0xd4, 0x02, 0xe0, 0x32, 0xa6, 0x33, 0x83, 0x6e, 0x41, 0x53, 0x18, 0x1d, - 0x7e, 0xb9, 0xbb, 0xbb, 0xfd, 0x52, 0x9b, 0x45, 0x1a, 0x34, 0xb8, 0x8a, 0x90, 0x54, 0x1e, 0x3d, - 0x07, 0x48, 0x66, 0x35, 0xca, 0x71, 0x77, 0x6f, 0x77, 0x5b, 0x9b, 0x42, 0x0d, 0xa8, 0xee, 0xee, - 0x99, 0xdb, 0xbb, 0x5b, 0xbd, 0x7d, 0xad, 0x84, 0x6a, 0x30, 0xcb, 0xd2, 0x9b, 0x56, 0xe6, 0xdd, - 0x18, 0xec, 0x6b, 0xd3, 0x1b, 0x9f, 0x00, 0xf0, 0x27, 0x24, 0xec, 0x7f, 0xaa, 0x9e, 0xc0, 0x0c, - 0xfb, 0xab, 0x9c, 0x9c, 0xfc, 0xa7, 0xd6, 0xaa, 0x94, 0xa5, 0xfe, 0x5b, 0xeb, 0x49, 0xe9, 0xc5, - 0xf2, 0x2f, 0xbe, 0x5d, 0x2b, 0xfd, 0xf3, 0xb7, 0x6b, 0xa5, 0x7f, 0xff, 0x76, 0xad, 0xf4, 0x97, - 0xff, 0xb1, 0x36, 0xf5, 0x93, 0x59, 0x76, 0x85, 0x7e, 0x5c, 0x61, 0x7f, 0x3e, 0xfa, 0xdf, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x43, 0xda, 0xdb, 0xf5, 0x0b, 0x36, 0x00, 0x00, + // 4243 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7b, 0xcd, 0x73, 0x1c, 0x49, + 0x5a, 0xb7, 0xaa, 0x25, 0xb5, 0xba, 0x9f, 0xfe, 0x74, 0xea, 0xab, 0x25, 0xdb, 0xb2, 0xa7, 0x3c, + 0xde, 0xd1, 0x78, 0x77, 0x3c, 0x7e, 0x35, 0x72, 0x7b, 0x3d, 0xef, 0x32, 0x1b, 0x6d, 0xb5, 0x66, + 0xd4, 0x33, 0xb6, 0x24, 0x4a, 0x1a, 0x0d, 0xb3, 0x6c, 0x44, 0x51, 0xaa, 0x4a, 0x49, 0x85, 0xab, + 0xab, 0x6a, 0xaa, 0xb2, 0xf5, 0xb1, 0x9c, 0x80, 0x25, 0x02, 0x82, 0x03, 0x1c, 0x08, 0x02, 0xee, + 0x9c, 0x08, 0xfe, 0x03, 0x0e, 0x5c, 0x77, 0x83, 0x0b, 0x04, 0x67, 0x22, 0x88, 0xe1, 0x46, 0x70, + 0x81, 0x08, 0xee, 0x44, 0x7e, 0xd6, 0x47, 0x57, 0xcb, 0x32, 0x3b, 0x70, 0x52, 0xe7, 0xf3, 0xf1, + 0xcb, 0x27, 0x9f, 0x7a, 0xf2, 0xc9, 0xcc, 0x27, 0x53, 0x80, 0x4e, 0xb0, 0xe7, 0x5e, 0x1e, 0x5b, + 0xf6, 0x6b, 0xec, 0x3b, 0x8f, 0xc3, 0x28, 0x20, 0x01, 0x9a, 0x65, 0x34, 0xbd, 0x01, 0xb5, 0x83, + 0x2b, 0xdf, 0x36, 0xf0, 0x37, 0x23, 0x1c, 0x13, 0xfd, 0xef, 0x97, 0xa0, 0x76, 0x18, 0xf4, 0x2d, + 0x62, 0x85, 0x9e, 0xe5, 0x63, 0xb4, 0x0e, 0x73, 0xae, 0x6f, 0xc6, 0x57, 0xbe, 0xdd, 0xd1, 0xee, + 0x6b, 0xeb, 0xb5, 0x8d, 0xc6, 0x63, 0xa6, 0xf7, 0x78, 0xe0, 0x53, 0xb5, 0x9d, 0x29, 0xa3, 0xec, + 0xb2, 0x5f, 0xe8, 0x19, 0xd4, 0xdd, 0x30, 0xc6, 0xc4, 0x1c, 0x85, 0x8e, 0x45, 0x70, 0xa7, 0xc4, + 0xc4, 0x91, 0x14, 0xdf, 0x3f, 0xc0, 0xe4, 0x4b, 0xc6, 0xd9, 0x99, 0x32, 0x6a, 0x4c, 0x92, 0x37, + 0xd1, 0x67, 0x80, 0xb8, 0xa2, 0x83, 0x3d, 0x62, 0x49, 0xf5, 0x69, 0xa6, 0xbe, 0x9c, 0x56, 0xef, + 0x53, 0xbe, 0xc2, 0x68, 0x33, 0xa5, 0x14, 0x2d, 0xb1, 0x20, 0xc2, 0xc3, 0xe0, 0x1c, 0x77, 0x66, + 0xc6, 0x2d, 0x30, 0x18, 0x47, 0x59, 0xc0, 0x9b, 0x68, 0x1f, 0x16, 0x2d, 0x9b, 0xb8, 0xe7, 0xd8, + 0x0c, 0xa3, 0xe0, 0xc4, 0xf5, 0xb0, 0x34, 0x62, 0x96, 0x21, 0xac, 0x0a, 0x84, 0x1e, 0x93, 0xd9, + 0xe7, 0x22, 0xca, 0x8e, 0x79, 0x6b, 0x9c, 0x5c, 0x80, 0x28, 0x6c, 0x2a, 0x4f, 0x46, 0x54, 0xb6, + 0x65, 0x11, 0x85, 0x8d, 0xaf, 0x60, 0x41, 0x22, 0x06, 0x9e, 0x6b, 0x5f, 0x49, 0x13, 0xe7, 0x18, + 0xe0, 0x4a, 0x16, 0x90, 0x49, 0x28, 0x0b, 0x91, 0x35, 0x46, 0x1d, 0x87, 0x13, 0xf6, 0x55, 0x26, + 0xc2, 0x29, 0xf3, 0x32, 0x70, 0x89, 0x75, 0x67, 0x41, 0x4c, 0x4c, 0xec, 0x3b, 0x61, 0xe0, 0xfa, + 0x2a, 0x08, 0xaa, 0x19, 0xb8, 0x9d, 0x20, 0x26, 0xdb, 0x42, 0x22, 0xb1, 0xee, 0x6c, 0x8c, 0x3a, + 0x0e, 0x27, 0xac, 0x83, 0x89, 0x70, 0x89, 0x75, 0x67, 0x63, 0x54, 0xf4, 0x35, 0x74, 0x2e, 0x82, + 0xe8, 0xb5, 0x17, 0x58, 0xce, 0x98, 0x85, 0x35, 0x06, 0x79, 0x57, 0x40, 0x7e, 0x25, 0xc4, 0xc6, + 0xac, 0x5c, 0xba, 0x28, 0xe4, 0x14, 0x43, 0x0b, 0x6b, 0xeb, 0xd7, 0x42, 0x2b, 0x8b, 0xc7, 0xa0, + 0x85, 0xd5, 0x1f, 0x43, 0xc3, 0x0e, 0xfc, 0x13, 0xf7, 0x54, 0x9a, 0xda, 0x60, 0x78, 0xf3, 0x02, + 0x6f, 0x8b, 0xf1, 0x94, 0x81, 0x75, 0x3b, 0xd5, 0x56, 0x0e, 0x1c, 0x62, 0x62, 0x39, 0x56, 0x32, + 0xab, 0x9a, 0x63, 0x0e, 0x7c, 0x25, 0x24, 0xb2, 0xdf, 0x23, 0x4b, 0x45, 0xef, 0x41, 0x2b, 0xa6, + 0x09, 0xc2, 0xb7, 0xb1, 0xe9, 0x8f, 0x86, 0xc7, 0x38, 0xea, 0xb4, 0xee, 0x6b, 0xeb, 0x33, 0x46, + 0x53, 0x92, 0x77, 0x19, 0x15, 0xf5, 0xa0, 0xed, 0x86, 0xd6, 0xd0, 0x0c, 0x83, 0xc0, 0x93, 0x7d, + 0xb6, 0x59, 0x9f, 0x8b, 0x6a, 0x1a, 0xf6, 0x5e, 0xed, 0x07, 0x81, 0xa7, 0xfa, 0x6b, 0x52, 0x85, + 0x84, 0x92, 0x85, 0x10, 0x9e, 0xbc, 0x55, 0x08, 0xa1, 0x3c, 0xa8, 0x20, 0x72, 0xd1, 0xa8, 0x46, + 0x2f, 0x60, 0xd0, 0xc4, 0xd1, 0x67, 0xc3, 0x27, 0x4b, 0x45, 0x07, 0xb0, 0x14, 0xe3, 0xe8, 0xdc, + 0xb5, 0xb1, 0x69, 0xd9, 0x76, 0x30, 0x4a, 0x82, 0x67, 0x9e, 0x01, 0xde, 0x16, 0x80, 0x07, 0x5c, + 0xa8, 0xc7, 0x65, 0xd4, 0x00, 0x17, 0xe2, 0x02, 0x7a, 0x11, 0xa8, 0xb0, 0x72, 0xe1, 0x1a, 0x50, + 0x65, 0x67, 0x0e, 0x54, 0x58, 0xba, 0x05, 0x6d, 0xdf, 0x1a, 0xe2, 0x38, 0xb4, 0x6c, 0x95, 0xc3, + 0x16, 0x19, 0xdc, 0x92, 0x80, 0xdb, 0x95, 0x6c, 0x65, 0x5e, 0xcb, 0xcf, 0x92, 0xb2, 0x20, 0xc2, + 0xa6, 0xa5, 0x62, 0x10, 0x65, 0x4e, 0x02, 0x22, 0x2c, 0x79, 0x06, 0xf5, 0x28, 0x18, 0x11, 0x65, + 0xc5, 0x72, 0x26, 0x17, 0x1b, 0x94, 0x95, 0xac, 0x06, 0x51, 0xd2, 0x4c, 0x14, 0x45, 0xcf, 0x9d, + 0x71, 0xc5, 0x24, 0x89, 0x47, 0x49, 0x13, 0x6d, 0x41, 0xed, 0x9c, 0xe0, 0x50, 0x76, 0xb8, 0xc2, + 0xf4, 0xee, 0x0b, 0xbd, 0xa3, 0xdf, 0x78, 0xd9, 0xdb, 0x3d, 0x1c, 0xf9, 0x3e, 0xf6, 0xc6, 0xa6, + 0x36, 0x50, 0x35, 0x35, 0x76, 0x0e, 0x22, 0x3a, 0x5f, 0x7d, 0x13, 0x88, 0x32, 0x85, 0x81, 0x08, + 0x4b, 0x7e, 0x0a, 0x2b, 0x17, 0x6e, 0x84, 0x4f, 0x47, 0x56, 0x34, 0x9e, 0x6f, 0x6e, 0x33, 0xc8, + 0x35, 0x99, 0x14, 0xa4, 0xdc, 0x98, 0x55, 0xcb, 0x17, 0xc5, 0xac, 0x09, 0xe8, 0xc2, 0xe0, 0x3b, + 0xd7, 0xa3, 0x2b, 0x73, 0xc7, 0xd1, 0x85, 0xed, 0x5f, 0x41, 0xe7, 0xd4, 0x0b, 0x8e, 0x2d, 0xcf, + 0x3c, 0x3e, 0x0d, 0xcd, 0x6c, 0xfe, 0xb9, 0xcb, 0xc0, 0xef, 0x08, 0xf0, 0xcf, 0x98, 0xd8, 0x8b, + 0xcf, 0xf6, 0x73, 0x89, 0x68, 0x91, 0xeb, 0xbf, 0x38, 0x0d, 0xd3, 0x0c, 0xf4, 0x23, 0x68, 0x60, + 0xdf, 0xb6, 0xc2, 0x78, 0xe4, 0x59, 0xc4, 0x0d, 0xfc, 0xce, 0x1a, 0x43, 0x5b, 0x10, 0x68, 0xdb, + 0x69, 0xde, 0xce, 0x94, 0x91, 0x15, 0x46, 0xbf, 0x06, 0x4d, 0x39, 0x5b, 0x84, 0x31, 0xf7, 0x32, + 0xea, 0x62, 0x96, 0x28, 0x23, 0x1a, 0x71, 0x9a, 0x90, 0x56, 0x17, 0x8e, 0xba, 0x5f, 0xa4, 0xae, + 0xdc, 0x23, 0xd5, 0x85, 0x53, 0x6c, 0xb8, 0x53, 0xe0, 0xf2, 0xf3, 0xae, 0xb4, 0xe5, 0x9d, 0x4c, + 0x98, 0x8c, 0x79, 0xfd, 0xa8, 0xab, 0xec, 0x5a, 0xb9, 0x98, 0xc4, 0x9c, 0xdc, 0x89, 0xb0, 0x58, + 0x7f, 0x53, 0x27, 0xca, 0xfa, 0xa2, 0x4e, 0xc4, 0x48, 0x0e, 0x61, 0x39, 0x9b, 0x19, 0x93, 0x41, + 0x3c, 0xc8, 0xa4, 0x9d, 0x74, 0x72, 0x4c, 0xd9, 0xbf, 0x70, 0x56, 0x40, 0x2f, 0x44, 0x15, 0x56, + 0xbf, 0x7b, 0x0d, 0x6a, 0x92, 0xcc, 0xce, 0x0a, 0xe8, 0xe8, 0x27, 0xb0, 0x92, 0x43, 0xdd, 0x4c, + 0xac, 0x7d, 0x98, 0x59, 0x5b, 0x33, 0xb8, 0x9b, 0x29, 0x7b, 0x97, 0x32, 0xc8, 0x9b, 0xe7, 0xd2, + 0xe2, 0x62, 0x6c, 0x61, 0xf3, 0xf7, 0xae, 0xc5, 0x4e, 0xd6, 0xed, 0x3c, 0x36, 0xe7, 0xbc, 0xa8, + 0xc2, 0x5c, 0x68, 0x5d, 0xd1, 0x05, 0x5d, 0xff, 0xa7, 0x59, 0x68, 0x7c, 0x1a, 0x05, 0xc3, 0x64, + 0x3f, 0xbd, 0x0f, 0x8b, 0x61, 0x14, 0xd8, 0x38, 0x8e, 0xcd, 0x98, 0x58, 0x64, 0x14, 0x67, 0xf7, + 0xbb, 0x72, 0x63, 0xb8, 0xcf, 0x65, 0x0e, 0x98, 0x48, 0xb2, 0xd5, 0x0c, 0xc7, 0xc9, 0xe8, 0xb7, + 0xe0, 0x76, 0x76, 0xaf, 0x94, 0xc5, 0xe5, 0x9b, 0xe0, 0x7b, 0x05, 0x5b, 0xa6, 0x1c, 0x78, 0xe7, + 0x6c, 0x02, 0x6f, 0x62, 0x0f, 0xc2, 0x5d, 0xb3, 0x6f, 0xe8, 0x41, 0x39, 0xac, 0xa0, 0x07, 0xf1, + 0xa9, 0x3d, 0xb8, 0x37, 0xbe, 0x8b, 0xca, 0x8e, 0x83, 0x6f, 0x9c, 0x1f, 0x4c, 0xd8, 0x4c, 0xe5, + 0xc6, 0x72, 0xe7, 0xe2, 0x1a, 0xfe, 0xb5, 0xbd, 0x89, 0x31, 0xcd, 0xdd, 0xa0, 0x37, 0x35, 0xae, + 0x09, 0xbd, 0x89, 0xb1, 0x15, 0xec, 0x9d, 0x2a, 0x85, 0x7b, 0xa7, 0x23, 0x48, 0xb2, 0x72, 0x6e, + 0xf0, 0xd5, 0x4c, 0xe6, 0x55, 0x73, 0x3f, 0x37, 0xea, 0xc5, 0x8b, 0x22, 0x06, 0xea, 0xc3, 0x2d, + 0x47, 0xc6, 0x9f, 0x29, 0x0f, 0x73, 0x90, 0x59, 0xd0, 0x55, 0x7c, 0xaa, 0x53, 0x5d, 0xcb, 0xc9, + 0x92, 0xd2, 0x51, 0xfd, 0x8f, 0x25, 0xa8, 0x67, 0x72, 0xfb, 0x33, 0x28, 0xf3, 0x95, 0xa2, 0xa3, + 0xdd, 0x9f, 0x4e, 0xc5, 0x42, 0x5a, 0x48, 0x34, 0xb6, 0x7d, 0x12, 0x5d, 0x19, 0x42, 0x1c, 0xfd, + 0x26, 0x2c, 0xc4, 0xc1, 0x28, 0xb2, 0xb1, 0x49, 0x02, 0x33, 0xb2, 0x2e, 0xc4, 0x82, 0xd3, 0x29, + 0x31, 0x98, 0x47, 0x45, 0x30, 0x07, 0x4c, 0xfe, 0x30, 0x30, 0xac, 0x8b, 0x34, 0xe2, 0xad, 0x38, + 0x4f, 0x47, 0x1d, 0x98, 0x1b, 0xe2, 0x38, 0xb6, 0x4e, 0xf9, 0xe4, 0xaa, 0x1a, 0xb2, 0xb9, 0xfa, + 0x1c, 0x6a, 0x29, 0x5d, 0xd4, 0x86, 0xe9, 0xd7, 0xf8, 0x8a, 0x9d, 0x6f, 0xab, 0x06, 0xfd, 0x89, + 0x16, 0x60, 0xf6, 0xdc, 0xf2, 0x46, 0xfc, 0x10, 0x5b, 0x35, 0x78, 0xe3, 0xe3, 0xd2, 0x0f, 0xb5, + 0xd5, 0x23, 0x58, 0x2a, 0xb6, 0x20, 0x8d, 0xd2, 0xe0, 0x28, 0xdf, 0x4b, 0xa3, 0xd4, 0x36, 0xda, + 0x72, 0x0f, 0x23, 0xf5, 0x52, 0xb8, 0xfa, 0x9f, 0x69, 0x50, 0x4d, 0x4c, 0x5f, 0x82, 0x32, 0x1f, + 0x8f, 0x30, 0x4a, 0xb4, 0xd0, 0xa6, 0x72, 0x34, 0xf7, 0xd0, 0x9d, 0x3c, 0x64, 0x91, 0x97, 0x7f, + 0x85, 0xe1, 0xea, 0x15, 0x28, 0xf3, 0xef, 0xaf, 0xff, 0x85, 0x06, 0xb5, 0xd4, 0x21, 0x1e, 0x35, + 0xa1, 0xe4, 0x3a, 0x02, 0xa4, 0xe4, 0x3a, 0xdc, 0xdb, 0x34, 0x8e, 0x63, 0x66, 0x1b, 0xf3, 0x36, + 0x6b, 0xa2, 0x27, 0x30, 0x43, 0xae, 0x42, 0xfe, 0x11, 0x9a, 0xca, 0xe4, 0x14, 0x16, 0xff, 0x7d, + 0x78, 0x15, 0x62, 0x83, 0x49, 0xea, 0x1f, 0x40, 0x55, 0x91, 0x50, 0x19, 0x4a, 0x83, 0xfd, 0xf6, + 0x14, 0x6a, 0xd1, 0xfe, 0xcd, 0xde, 0x6e, 0xdf, 0xdc, 0xdf, 0x33, 0x0e, 0xdb, 0x1a, 0x9a, 0x83, + 0xe9, 0xdd, 0xed, 0xc3, 0x76, 0x49, 0x0f, 0xa1, 0x9d, 0xaf, 0x0f, 0x8c, 0x99, 0xf7, 0x00, 0x1a, + 0x96, 0xe3, 0x60, 0xc7, 0xcc, 0x1a, 0x59, 0x67, 0xc4, 0x57, 0xc2, 0xd2, 0xf7, 0xa0, 0xc5, 0xe7, + 0x7f, 0x22, 0x36, 0xcd, 0xc4, 0x9a, 0x82, 0x2c, 0x04, 0xf5, 0xbb, 0xc2, 0x17, 0x62, 0x8a, 0xe7, + 0x3a, 0xd3, 0x2d, 0x98, 0x2f, 0xa8, 0x15, 0xa0, 0xfb, 0x4a, 0x2c, 0x09, 0x06, 0x21, 0x31, 0xe8, + 0x33, 0x2b, 0xd7, 0x61, 0x4e, 0xd4, 0x0b, 0x44, 0xcc, 0x34, 0xb3, 0x62, 0x86, 0x64, 0xeb, 0xcf, + 0x72, 0x5d, 0x08, 0x4b, 0xde, 0xd8, 0x85, 0x7e, 0x0f, 0xaa, 0x8a, 0x80, 0x10, 0xcc, 0xd0, 0x8d, + 0xbb, 0x30, 0x9d, 0xfd, 0xd6, 0x03, 0x98, 0x13, 0x02, 0xe8, 0x09, 0x34, 0x5c, 0xff, 0x38, 0x18, + 0xf9, 0x8e, 0x19, 0x8d, 0x3c, 0x1c, 0x8b, 0xe9, 0x5d, 0x93, 0x51, 0x37, 0xf2, 0xb0, 0x51, 0x17, + 0x12, 0xb4, 0x11, 0xa3, 0x0d, 0x68, 0x06, 0x23, 0x92, 0x56, 0x29, 0x8d, 0xab, 0x34, 0xa4, 0x08, + 0xd3, 0xd1, 0x7f, 0x0a, 0x68, 0xbc, 0x6c, 0x81, 0xee, 0xa5, 0x46, 0xd2, 0x92, 0x23, 0x61, 0x02, + 0xc2, 0x57, 0x0f, 0xa1, 0xcc, 0x4b, 0x17, 0xc2, 0x55, 0x8d, 0x8c, 0x90, 0x21, 0x98, 0xfa, 0xd3, + 0x2c, 0xba, 0xf0, 0xd3, 0x9b, 0xd0, 0xf5, 0x0d, 0xa8, 0xc8, 0x36, 0xf5, 0x12, 0x71, 0x71, 0x24, + 0xbd, 0x44, 0x7f, 0x2b, 0xcf, 0x95, 0x52, 0x9e, 0xfb, 0x4f, 0x0d, 0xca, 0x5c, 0xe9, 0xff, 0xc6, + 0x73, 0xe8, 0x0e, 0x54, 0x47, 0x3e, 0x89, 0x2c, 0xfb, 0x35, 0x76, 0xd8, 0xf4, 0xaa, 0x18, 0x09, + 0x01, 0xad, 0x40, 0x25, 0x8c, 0xb0, 0xe9, 0xf8, 0x16, 0x61, 0xbb, 0x80, 0x0a, 0x8d, 0x1e, 0xdc, + 0xf7, 0x2d, 0x42, 0x15, 0xd5, 0x81, 0x8d, 0xad, 0xdf, 0x55, 0x23, 0x21, 0xa0, 0xef, 0xc3, 0xad, + 0x20, 0x72, 0x4f, 0x5d, 0xdf, 0xf2, 0xcc, 0x18, 0x7b, 0xd8, 0x26, 0x41, 0xc4, 0xd6, 0xdf, 0xaa, + 0xd1, 0x96, 0x8c, 0x03, 0x41, 0xd7, 0xff, 0xba, 0x0d, 0x33, 0xd4, 0x1a, 0x9a, 0xb3, 0x2c, 0x9b, + 0xed, 0xec, 0x45, 0xce, 0xe2, 0x2d, 0xf4, 0x21, 0x80, 0x1b, 0x9a, 0xe7, 0x38, 0x8a, 0x29, 0xaf, + 0xc4, 0x92, 0x40, 0x5b, 0x25, 0x81, 0x23, 0x4e, 0x37, 0xaa, 0x6e, 0x28, 0x7e, 0xa2, 0xef, 0x53, + 0xbb, 0x03, 0x12, 0xd8, 0x81, 0x27, 0x76, 0x45, 0xad, 0x24, 0x92, 0x19, 0xd9, 0x50, 0x02, 0x68, + 0x19, 0xe6, 0xe2, 0xc8, 0x36, 0x7d, 0x4c, 0xc7, 0x38, 0xcd, 0x52, 0x65, 0x64, 0xef, 0x62, 0x82, + 0x3e, 0x80, 0x2a, 0x65, 0x84, 0x41, 0x44, 0xe2, 0xce, 0x2c, 0x73, 0xa5, 0x9a, 0x10, 0x41, 0x44, + 0x0c, 0xcb, 0x3f, 0xc5, 0x46, 0x25, 0x8e, 0x6c, 0xda, 0x8a, 0x29, 0x8e, 0x13, 0x13, 0x86, 0x53, + 0xe6, 0x38, 0x4e, 0x4c, 0x04, 0x0e, 0x65, 0x70, 0x9c, 0xb9, 0x49, 0x38, 0x4e, 0x4c, 0x38, 0xce, + 0x5d, 0xa8, 0xba, 0xf6, 0x30, 0x34, 0x59, 0xc6, 0xa3, 0xeb, 0xfc, 0xec, 0xce, 0x94, 0x51, 0xa1, + 0x24, 0x96, 0xcc, 0x3e, 0x81, 0xa6, 0x62, 0x9b, 0x76, 0xe0, 0xc8, 0xa5, 0x5d, 0x2e, 0xc4, 0x03, + 0x21, 0xd8, 0xf3, 0x9d, 0xad, 0xc0, 0x61, 0x75, 0x1d, 0xa9, 0x4b, 0xdb, 0xe8, 0x01, 0x34, 0xe9, + 0xa8, 0xdc, 0xd0, 0x8c, 0x31, 0x31, 0x5d, 0x27, 0xee, 0x00, 0xb3, 0xb6, 0x16, 0x47, 0xf6, 0x20, + 0x3c, 0xc0, 0x64, 0xe0, 0xc4, 0x54, 0x88, 0x9a, 0x9c, 0x12, 0xaa, 0x71, 0x21, 0x27, 0x26, 0x4a, + 0xe8, 0x19, 0xac, 0x30, 0xc7, 0x59, 0x43, 0xec, 0xb0, 0xd1, 0xa5, 0xe5, 0xeb, 0x4c, 0x7e, 0x81, + 0xba, 0x92, 0xf2, 0xe9, 0xd0, 0xd2, 0x8a, 0xcc, 0x53, 0x85, 0x8a, 0x0d, 0xae, 0x48, 0x7d, 0x37, + 0xa6, 0xf8, 0x03, 0x98, 0x17, 0x66, 0x31, 0x2d, 0xa9, 0xd2, 0x62, 0x2a, 0x2d, 0x66, 0x1b, 0x95, + 0x17, 0xd2, 0x1b, 0x50, 0xf7, 0x03, 0x62, 0xaa, 0x48, 0x38, 0x29, 0x8e, 0x84, 0x9a, 0x1f, 0x10, + 0xd9, 0x40, 0x6b, 0x40, 0x9b, 0xa6, 0x0c, 0x88, 0x53, 0x86, 0x5c, 0xf5, 0x03, 0x72, 0xc0, 0x63, + 0x62, 0x13, 0x1a, 0x92, 0xcf, 0xbf, 0xe7, 0xd9, 0x84, 0xef, 0x59, 0xe3, 0x3a, 0xfc, 0x93, 0x0a, + 0x54, 0x19, 0x1e, 0xae, 0x42, 0xed, 0xf3, 0x08, 0x11, 0xa8, 0x49, 0x94, 0xfc, 0xf6, 0x35, 0xa8, + 0x7d, 0x19, 0x28, 0xef, 0x72, 0xad, 0x24, 0x58, 0x5e, 0xb3, 0x60, 0xd1, 0x98, 0x94, 0x0c, 0x03, + 0xb4, 0x0d, 0x28, 0x23, 0xc5, 0x63, 0xc6, 0xbb, 0x36, 0x66, 0x34, 0xa3, 0x95, 0x82, 0x60, 0x61, + 0xf3, 0x88, 0xc3, 0xe4, 0x42, 0x67, 0xc8, 0xd7, 0x36, 0x3e, 0x56, 0xf5, 0x99, 0x84, 0x6c, 0x2e, + 0x82, 0x7c, 0x25, 0xdb, 0x4f, 0x05, 0xd1, 0x27, 0x70, 0x57, 0x39, 0xbc, 0x30, 0x1e, 0x42, 0xa6, + 0xb6, 0x2c, 0x3e, 0xc1, 0x58, 0x48, 0x08, 0xfd, 0xc9, 0xf1, 0xf4, 0x8d, 0xd2, 0xef, 0x17, 0x85, + 0xd4, 0x06, 0x2c, 0x26, 0x99, 0x2a, 0xb2, 0x93, 0x6c, 0x15, 0xb1, 0x14, 0x34, 0xaf, 0xb2, 0x55, + 0x64, 0xcb, 0x84, 0x95, 0xd1, 0xa1, 0x1d, 0x2b, 0x9d, 0x38, 0xab, 0xd3, 0x8f, 0x89, 0xd2, 0xd9, + 0x86, 0x7b, 0x99, 0x7e, 0x92, 0xfa, 0x98, 0xd2, 0x26, 0x4c, 0xfb, 0x4e, 0xaa, 0x47, 0x55, 0x25, + 0x2b, 0x84, 0x91, 0x63, 0xce, 0xc1, 0x8c, 0xb2, 0x30, 0x62, 0xd4, 0x59, 0x98, 0xe7, 0xb0, 0xa2, + 0x60, 0xa4, 0xfb, 0x15, 0xc0, 0x39, 0x03, 0x58, 0x92, 0x02, 0xbb, 0xcc, 0xf3, 0x13, 0x55, 0x33, + 0x0e, 0xb8, 0x18, 0x53, 0x4d, 0xfb, 0xe0, 0x4b, 0x9e, 0x30, 0xf2, 0x45, 0xcb, 0xa1, 0x45, 0xec, + 0xb3, 0xce, 0x65, 0xe6, 0xf4, 0x9a, 0xad, 0x59, 0xbe, 0xa2, 0x12, 0xc6, 0x52, 0x4c, 0xcd, 0x18, + 0xa3, 0x53, 0x58, 0x6e, 0x44, 0x11, 0xec, 0xd5, 0x9b, 0x61, 0x1d, 0x6a, 0xe2, 0x38, 0xec, 0x87, + 0x00, 0x67, 0x84, 0x84, 0x02, 0xe7, 0x67, 0x99, 0x0d, 0xd1, 0xce, 0xe1, 0xe1, 0x3e, 0xd7, 0xae, + 0x52, 0x19, 0xa9, 0x50, 0x91, 0xc5, 0x80, 0xce, 0xef, 0x64, 0x0a, 0xed, 0x74, 0x75, 0x53, 0x15, + 0x61, 0x25, 0x84, 0xfe, 0x1f, 0x2c, 0xe4, 0xe2, 0x88, 0x59, 0xd1, 0xf9, 0x3d, 0xbe, 0xfc, 0xa1, + 0x4c, 0x1c, 0x31, 0x16, 0xea, 0xc3, 0x5a, 0x91, 0x4a, 0x12, 0x07, 0x9d, 0xdf, 0xe7, 0xca, 0xb7, + 0xc7, 0x95, 0x55, 0x18, 0x64, 0x3a, 0x4e, 0x7d, 0x91, 0xce, 0xcf, 0x73, 0x1d, 0x1f, 0x28, 0x87, + 0x67, 0x3a, 0x4e, 0x7f, 0xc4, 0xa4, 0xe3, 0x3f, 0xc8, 0x75, 0x9c, 0x28, 0x27, 0x1d, 0x77, 0x60, + 0x8e, 0xee, 0x4c, 0x4c, 0xd7, 0xe9, 0xfc, 0x52, 0xac, 0xf1, 0xb4, 0x3d, 0x70, 0x5e, 0x94, 0x61, + 0x86, 0xa6, 0xa8, 0x17, 0x00, 0x15, 0x99, 0xae, 0x3e, 0x2f, 0x57, 0x7e, 0xa1, 0xb5, 0x7f, 0xa9, + 0x19, 0xe0, 0x05, 0xa7, 0x66, 0x18, 0xe1, 0x13, 0xf7, 0x52, 0xff, 0x0c, 0xe6, 0x8b, 0x3e, 0xd6, + 0x2a, 0x54, 0x54, 0x10, 0x72, 0x60, 0xd5, 0xa6, 0x67, 0x13, 0x66, 0xa5, 0xd8, 0xb0, 0xf3, 0x86, + 0xfe, 0x57, 0x1a, 0x54, 0xd5, 0x67, 0xe4, 0x67, 0x0f, 0x72, 0x16, 0x38, 0x7c, 0x9f, 0xc5, 0xce, + 0x1e, 0xac, 0x89, 0x9e, 0xc0, 0x6c, 0x68, 0x91, 0x33, 0xb9, 0x99, 0x5a, 0xcd, 0x47, 0xc0, 0xe3, + 0x7d, 0x8b, 0x9c, 0xf1, 0x58, 0xe0, 0x82, 0xab, 0x5f, 0x40, 0x55, 0xd1, 0xd0, 0x12, 0xcc, 0xe2, + 0x4b, 0xcb, 0x26, 0xdc, 0xaa, 0x9d, 0x29, 0x83, 0x37, 0x51, 0x07, 0xca, 0x7c, 0x44, 0x7c, 0xff, + 0xb7, 0x33, 0x65, 0x88, 0xf6, 0x8b, 0x3a, 0x00, 0xc5, 0xe1, 0x71, 0xa7, 0xff, 0xb9, 0x06, 0xf5, + 0x74, 0xf8, 0xa0, 0x4f, 0xa1, 0x66, 0xf9, 0x7e, 0x40, 0x58, 0x55, 0x53, 0xee, 0x0a, 0xdf, 0x2d, + 0x08, 0xb4, 0xc7, 0xbd, 0x44, 0x8c, 0x9f, 0xe6, 0xd2, 0x8a, 0xab, 0x9f, 0x40, 0x3b, 0x2f, 0xf0, + 0x56, 0xe7, 0xba, 0xe7, 0xd0, 0xca, 0x2d, 0x1b, 0x6c, 0x97, 0x4b, 0xd7, 0x21, 0xaa, 0x3f, 0xcb, + 0x0f, 0x62, 0x94, 0xc6, 0x16, 0x9c, 0x12, 0xa7, 0xd1, 0xdf, 0xfa, 0x4b, 0xa8, 0xa8, 0x05, 0xb7, + 0x03, 0x65, 0x51, 0xd2, 0xd0, 0xc4, 0x56, 0x47, 0xb4, 0xd1, 0x42, 0x7a, 0x7f, 0xbc, 0x33, 0xc5, + 0x77, 0xc8, 0x2f, 0xda, 0xd0, 0xe4, 0x7c, 0x33, 0x88, 0x58, 0xf0, 0xe9, 0x4f, 0xa1, 0xaa, 0x16, + 0x48, 0x6a, 0xef, 0x89, 0x1b, 0xc5, 0x44, 0xd8, 0xc0, 0x1b, 0xd4, 0x08, 0xcf, 0x8a, 0x89, 0x34, + 0x82, 0xfe, 0xd6, 0xff, 0x44, 0x03, 0x94, 0xaf, 0xca, 0x0c, 0xfa, 0xf4, 0x00, 0x17, 0x44, 0xf6, + 0x19, 0x8e, 0x49, 0x64, 0x91, 0x20, 0xa2, 0x91, 0xca, 0x87, 0xde, 0x4c, 0x93, 0x07, 0x0e, 0xba, + 0x07, 0x35, 0x55, 0x02, 0x72, 0x1d, 0x51, 0x1f, 0x00, 0x49, 0xe2, 0x02, 0xaa, 0x34, 0xe4, 0x3a, + 0x6c, 0xff, 0x5c, 0x35, 0x40, 0x92, 0x06, 0xce, 0xe7, 0x33, 0x15, 0xad, 0x5d, 0x32, 0x2a, 0x67, + 0x41, 0x4c, 0xd8, 0x40, 0x2e, 0x61, 0xa9, 0xf8, 0xf2, 0x10, 0xbd, 0x9f, 0x3a, 0x6b, 0xac, 0x4c, + 0xa8, 0x28, 0x89, 0x33, 0xcd, 0x47, 0x50, 0x91, 0x5d, 0x88, 0xb2, 0xda, 0xf2, 0xa4, 0xdb, 0x43, + 0x25, 0xa8, 0xff, 0xd7, 0x34, 0xb4, 0xf3, 0x6c, 0xea, 0xca, 0x98, 0x58, 0x44, 0x1e, 0xed, 0x78, + 0xa3, 0xe8, 0xd4, 0x42, 0xc3, 0x66, 0x68, 0xd9, 0xc2, 0x05, 0xf4, 0x27, 0x1d, 0xbb, 0xbc, 0xb5, + 0xa6, 0x6b, 0x30, 0xdf, 0x57, 0x83, 0x20, 0xd1, 0x65, 0xf7, 0x36, 0x54, 0xdd, 0xf0, 0x7c, 0x93, + 0x6e, 0x87, 0xf8, 0xde, 0xba, 0x6a, 0x54, 0x28, 0x61, 0x17, 0x13, 0xc9, 0xec, 0x72, 0x66, 0x59, + 0x31, 0xbb, 0x8c, 0xf9, 0x10, 0x66, 0xe9, 0xf1, 0x49, 0xee, 0xa4, 0xe5, 0x76, 0xee, 0xd0, 0xc5, + 0xd1, 0xc0, 0x3f, 0x09, 0x0c, 0xce, 0x45, 0xef, 0x43, 0x85, 0x77, 0x60, 0x91, 0x4e, 0x85, 0x49, + 0x36, 0xd5, 0xd5, 0x13, 0x61, 0x82, 0x73, 0xac, 0x3f, 0x8b, 0x08, 0xd1, 0x2e, 0x13, 0xad, 0x4e, + 0x14, 0xed, 0x52, 0xd1, 0x1e, 0xdc, 0xb5, 0x3c, 0x2f, 0xb8, 0x30, 0xe3, 0x30, 0x08, 0x4e, 0xb0, + 0x63, 0x8a, 0xda, 0x13, 0x9f, 0xba, 0x58, 0xee, 0xa5, 0x57, 0x99, 0xd0, 0x01, 0x97, 0xe1, 0xc5, + 0x9e, 0x7d, 0x21, 0x81, 0x3e, 0xcf, 0xce, 0xdf, 0x1a, 0xeb, 0x70, 0x7d, 0xc2, 0x37, 0xfa, 0x5f, + 0x9e, 0xc3, 0x5b, 0xe3, 0x11, 0x27, 0x4e, 0xb7, 0x37, 0x8f, 0x38, 0xbd, 0x07, 0xcd, 0x74, 0xc5, + 0x76, 0xd0, 0xcf, 0x47, 0x7e, 0xe9, 0x8d, 0x91, 0xef, 0x01, 0x1a, 0xbf, 0xd8, 0x47, 0x0f, 0x53, + 0x36, 0x2c, 0x16, 0xd4, 0x86, 0x45, 0xc4, 0x7f, 0x98, 0x8a, 0xf8, 0xe9, 0xcc, 0xb2, 0x9b, 0xb9, + 0xdd, 0x4f, 0xa2, 0xfd, 0x3f, 0x4a, 0x50, 0x4f, 0xb3, 0x8a, 0x6a, 0x18, 0xf9, 0x08, 0x2e, 0x8d, + 0x45, 0xb0, 0x8a, 0xc3, 0xe9, 0x6b, 0xe3, 0xf0, 0x31, 0xcc, 0xe3, 0xcb, 0x10, 0xdb, 0x04, 0x3b, + 0x26, 0x0b, 0x48, 0xcb, 0x71, 0x22, 0x39, 0x23, 0x6e, 0x49, 0xd6, 0x20, 0x3c, 0xdf, 0xec, 0x51, + 0x46, 0x5e, 0xbe, 0x2b, 0xe4, 0x67, 0xc7, 0xe4, 0xbb, 0x5c, 0xfe, 0x87, 0xd0, 0x52, 0xe7, 0x75, + 0x93, 0x1b, 0x54, 0x2e, 0x36, 0xa8, 0xa9, 0xe4, 0x0e, 0x99, 0x65, 0x4f, 0xa1, 0x29, 0x0f, 0xf7, + 0xe6, 0xb5, 0x33, 0xaa, 0x2e, 0xce, 0xfc, 0x5c, 0x6d, 0x13, 0x1a, 0x27, 0x41, 0x74, 0x61, 0x45, + 0xb2, 0xbb, 0xca, 0x04, 0x2d, 0x21, 0xc5, 0xb4, 0xf4, 0xff, 0x9f, 0xfd, 0xc2, 0x22, 0xca, 0x6e, + 0xf6, 0x85, 0xf5, 0xbf, 0xd4, 0xa0, 0x22, 0x71, 0x0b, 0x3f, 0xd6, 0xfb, 0xd0, 0x76, 0xfd, 0xd3, + 0x08, 0xc7, 0x31, 0x7f, 0x8b, 0xe2, 0xaa, 0xc5, 0xbe, 0x25, 0xe8, 0xfb, 0x82, 0x4c, 0xf3, 0x3b, + 0xce, 0x49, 0x8a, 0x02, 0x1d, 0xce, 0x0a, 0x3e, 0x84, 0xa6, 0x83, 0x4f, 0xac, 0x91, 0x47, 0x4c, + 0x51, 0x94, 0xe0, 0x19, 0xbc, 0x21, 0xa8, 0x3d, 0x46, 0xd4, 0x9f, 0xc1, 0x9c, 0xc8, 0x12, 0x68, + 0x11, 0xca, 0xf8, 0x92, 0x9e, 0x3d, 0x64, 0xc6, 0xc4, 0x97, 0x64, 0x10, 0x52, 0x32, 0x9b, 0x08, + 0xa1, 0x9c, 0x7f, 0x74, 0x60, 0xa1, 0x6e, 0xc0, 0x7c, 0xc1, 0x15, 0x0d, 0x7a, 0x00, 0x0d, 0x37, + 0x0e, 0x4c, 0xe2, 0x0e, 0x71, 0x4c, 0xac, 0xa1, 0xc4, 0xaa, 0xbb, 0x71, 0x70, 0x28, 0x69, 0x68, + 0x09, 0xca, 0xa3, 0x90, 0x8a, 0x30, 0x48, 0xcd, 0x10, 0x2d, 0x3d, 0x84, 0xce, 0xa4, 0xeb, 0x99, + 0x9b, 0xce, 0xa6, 0x0f, 0xa0, 0xcc, 0x2f, 0x0e, 0x44, 0x4d, 0x6c, 0x51, 0xdd, 0xae, 0x66, 0x2e, + 0x26, 0x84, 0x90, 0xbe, 0x0e, 0xcd, 0x2c, 0x87, 0x15, 0x9e, 0x39, 0x80, 0x2c, 0x3c, 0x73, 0xc9, + 0x5e, 0x91, 0x6d, 0x6f, 0x17, 0x07, 0x97, 0x70, 0xe7, 0xba, 0x5b, 0x9b, 0xb7, 0x59, 0x26, 0xdf, + 0x72, 0x98, 0x83, 0x49, 0x3d, 0xbf, 0x7d, 0xba, 0x3c, 0x85, 0xc5, 0xc2, 0xdb, 0x17, 0x74, 0x17, + 0x20, 0x1c, 0x1d, 0x7b, 0xae, 0x6d, 0x26, 0xf9, 0xbb, 0xca, 0x29, 0x5f, 0xe0, 0xab, 0xb7, 0x2e, + 0x82, 0xe9, 0xb7, 0xa0, 0x95, 0xbb, 0x94, 0xd1, 0xff, 0xb0, 0x04, 0x4b, 0xc5, 0x17, 0x9d, 0x74, + 0x03, 0x2d, 0xd3, 0xb1, 0xdc, 0x40, 0xcb, 0xb6, 0x5a, 0xac, 0x69, 0x2a, 0x12, 0x41, 0xcc, 0x16, + 0x57, 0x9a, 0x81, 0xd4, 0x62, 0xcd, 0x98, 0xd3, 0x8a, 0xc9, 0xd2, 0x13, 0x45, 0xb5, 0x62, 0xb1, + 0xbf, 0xe3, 0xd3, 0x47, 0xb5, 0x51, 0x0f, 0xca, 0x9e, 0x75, 0x8c, 0x3d, 0x59, 0x5b, 0x7b, 0xff, + 0xda, 0x9b, 0xd8, 0xc7, 0x2f, 0x99, 0xac, 0xb8, 0x96, 0xe0, 0x8a, 0xab, 0xcf, 0xa1, 0x96, 0x22, + 0xbf, 0xd5, 0xd2, 0xf7, 0xeb, 0xe3, 0x9e, 0x10, 0xdf, 0xf2, 0x7f, 0xea, 0x09, 0xfd, 0x15, 0xcf, + 0x71, 0xb9, 0x87, 0x4f, 0xdf, 0x15, 0xdc, 0xaf, 0x6a, 0xdd, 0x1e, 0x2c, 0x14, 0xdd, 0xc8, 0xdf, + 0x00, 0xb0, 0x9b, 0x07, 0xec, 0x16, 0x03, 0xde, 0xd8, 0xc2, 0x09, 0x80, 0xdb, 0xd0, 0xcc, 0x3e, + 0xed, 0x2a, 0xb8, 0x82, 0x99, 0x09, 0x83, 0xc0, 0x13, 0x73, 0xb6, 0x95, 0x7f, 0xcc, 0xc5, 0x98, + 0xfa, 0xfd, 0x04, 0x66, 0xc2, 0xe5, 0xca, 0xcf, 0xa0, 0x22, 0x25, 0xd8, 0xf9, 0xc4, 0x75, 0x54, + 0x65, 0x9e, 0xfe, 0x46, 0x6b, 0x00, 0x43, 0x2b, 0xfe, 0x66, 0x84, 0x23, 0x4b, 0x9c, 0x5c, 0x2a, + 0x46, 0x8a, 0xc2, 0x47, 0xe1, 0x86, 0xe6, 0x90, 0x1e, 0x6c, 0x54, 0xc8, 0xbb, 0xe1, 0x2b, 0x7a, + 0x08, 0xba, 0x0b, 0x70, 0x7e, 0xe9, 0x59, 0x3e, 0xe7, 0xf2, 0xa0, 0xaf, 0x32, 0x0a, 0x65, 0xeb, + 0xbf, 0xab, 0x41, 0x23, 0xf3, 0x52, 0x05, 0xbd, 0x03, 0x75, 0x86, 0x86, 0x7d, 0xeb, 0xd8, 0xc3, + 0xdc, 0xce, 0x8a, 0x51, 0xa3, 0xb4, 0x6d, 0x4e, 0xa2, 0x8b, 0x02, 0xc7, 0x94, 0x32, 0xdc, 0xa6, + 0x3a, 0x23, 0x4a, 0xa1, 0x75, 0x68, 0x67, 0x84, 0xcc, 0xf3, 0xae, 0xa8, 0xe8, 0x37, 0xd3, 0x72, + 0x47, 0x5d, 0xfd, 0x6f, 0x35, 0x58, 0x28, 0x7a, 0x69, 0x86, 0xde, 0x4b, 0xa5, 0xb1, 0xe5, 0xc2, + 0x92, 0x89, 0x48, 0x9f, 0x3f, 0x56, 0x73, 0x97, 0x9f, 0x8a, 0xdf, 0xbb, 0xe6, 0xfd, 0xda, 0x77, + 0x3d, 0x73, 0x7f, 0x9c, 0x37, 0x5e, 0xdd, 0x92, 0xdf, 0xcc, 0x78, 0xbd, 0x0f, 0xed, 0x3c, 0x3d, + 0x7b, 0x9d, 0xa1, 0xe5, 0xaf, 0x33, 0x8a, 0xae, 0x6a, 0xfe, 0x46, 0x83, 0x56, 0xee, 0x29, 0x1c, + 0xd2, 0x53, 0x26, 0xa0, 0xfc, 0x4b, 0x37, 0xe1, 0xba, 0x8f, 0x73, 0xae, 0xd3, 0x8b, 0x9f, 0xd5, + 0x7d, 0xd7, 0x5e, 0x7b, 0x9a, 0xb2, 0x56, 0x38, 0xec, 0x06, 0xd6, 0xea, 0xef, 0x40, 0x2d, 0x45, + 0x2a, 0xbc, 0xed, 0x3b, 0x04, 0xe0, 0x2f, 0xda, 0x0e, 0xc5, 0x79, 0x9f, 0x46, 0xae, 0x88, 0x62, + 0xf6, 0x9b, 0x59, 0x45, 0x23, 0x50, 0x84, 0x2d, 0x6f, 0x50, 0x97, 0xab, 0xd7, 0x06, 0xf2, 0xea, + 0x49, 0x11, 0xf4, 0x7f, 0x2e, 0x41, 0x2d, 0xf5, 0xc6, 0x0f, 0xbd, 0x9b, 0xaa, 0x2d, 0x24, 0x0b, + 0x1f, 0x93, 0x48, 0xae, 0x7d, 0xd1, 0x47, 0x74, 0x2e, 0xf1, 0x77, 0x9f, 0x4c, 0x9a, 0x2f, 0x93, + 0xb7, 0x54, 0xa2, 0xa0, 0x53, 0x9e, 0x89, 0x83, 0x1b, 0xca, 0xdf, 0xd4, 0x8d, 0x4e, 0x4c, 0xe4, + 0xf1, 0xd5, 0x89, 0x09, 0xd2, 0xa1, 0xc1, 0x8a, 0xab, 0x81, 0xc3, 0x0b, 0x5c, 0x62, 0x1a, 0xd7, + 0x9c, 0x98, 0xec, 0x06, 0x0e, 0xab, 0x67, 0xa1, 0x35, 0xa8, 0x29, 0x19, 0x37, 0x94, 0x57, 0x60, + 0x42, 0x62, 0x10, 0xd2, 0x03, 0x44, 0x6c, 0x0d, 0xb1, 0x19, 0x8f, 0x8e, 0x7d, 0x4c, 0xd8, 0x73, + 0x90, 0x8a, 0x01, 0x94, 0x74, 0xc0, 0x28, 0x74, 0xde, 0xd3, 0xad, 0x77, 0x30, 0x22, 0xa7, 0x81, + 0xeb, 0x9f, 0xb2, 0xab, 0x9e, 0x8a, 0x51, 0xf3, 0x2d, 0xb2, 0x27, 0x48, 0x74, 0x0f, 0xea, 0x05, + 0xb6, 0xe5, 0x99, 0xb2, 0xac, 0xc0, 0xee, 0x7a, 0x2a, 0x46, 0x83, 0x51, 0xe5, 0x06, 0x03, 0x6d, + 0x40, 0x8d, 0xb0, 0x2f, 0xc0, 0x07, 0xcd, 0x1f, 0x66, 0xc8, 0x41, 0x27, 0xdf, 0xc6, 0x00, 0xa2, + 0x7e, 0xeb, 0xf7, 0x84, 0x7b, 0x45, 0x2c, 0x08, 0x1f, 0x94, 0x94, 0x0f, 0xf4, 0x7f, 0xd3, 0x60, + 0x65, 0xe2, 0x9b, 0x47, 0x16, 0x08, 0x34, 0xbf, 0xc9, 0x40, 0xa0, 0x99, 0x4f, 0x94, 0x01, 0x4a, + 0x49, 0x19, 0x20, 0xb3, 0x20, 0x4d, 0xe7, 0x36, 0x0e, 0xeb, 0xd0, 0x0e, 0xad, 0x08, 0xfb, 0xc4, + 0x74, 0x30, 0x2b, 0x25, 0xba, 0xa1, 0xf0, 0x73, 0x93, 0xd3, 0xfb, 0x8c, 0xcc, 0x77, 0xd0, 0x43, + 0xcb, 0xa6, 0xf9, 0x8c, 0x7b, 0x79, 0x76, 0x68, 0xd9, 0x47, 0xdd, 0xec, 0x62, 0x52, 0xce, 0xed, + 0x3c, 0x7e, 0x00, 0x28, 0x8f, 0x7e, 0xde, 0x65, 0x5f, 0xa1, 0x6a, 0xb4, 0xb3, 0xf8, 0xe7, 0x5d, + 0xfd, 0xc3, 0xc2, 0xb1, 0x0a, 0xdf, 0x14, 0x8c, 0x55, 0xff, 0xb9, 0x06, 0xcb, 0x13, 0x5e, 0x5e, + 0x5e, 0xbb, 0x00, 0x66, 0x37, 0x79, 0xa5, 0xfc, 0x26, 0xef, 0x31, 0xcc, 0xbb, 0x3e, 0xc1, 0xd1, + 0x89, 0xc5, 0x2d, 0xce, 0xb8, 0xee, 0x96, 0x62, 0xc9, 0xe3, 0xa2, 0xfe, 0xb4, 0xc0, 0x8a, 0x37, + 0x2f, 0xc3, 0xfa, 0x1f, 0x6b, 0xb0, 0x32, 0xf1, 0x8d, 0xe1, 0xb5, 0xf6, 0xeb, 0xd0, 0x48, 0xec, + 0xa7, 0x5f, 0x84, 0x0f, 0xa1, 0xa6, 0x86, 0x70, 0xd4, 0x1d, 0x1b, 0x44, 0x77, 0xe2, 0x20, 0xf8, + 0xba, 0xff, 0xac, 0xd0, 0x98, 0x1b, 0x0c, 0xe3, 0xef, 0x34, 0x58, 0x2c, 0x7c, 0x43, 0x8a, 0x36, + 0x60, 0x51, 0x16, 0xa8, 0x6d, 0x6f, 0x14, 0x13, 0x1c, 0x99, 0x74, 0x65, 0x97, 0xc5, 0xdd, 0x79, + 0xc1, 0xdc, 0xe2, 0xbc, 0x2d, 0xca, 0x42, 0x9b, 0xc9, 0x73, 0x6a, 0x7c, 0x49, 0x70, 0xe4, 0x5b, + 0x9e, 0x50, 0x2a, 0x89, 0xbb, 0x4c, 0xce, 0xdd, 0x16, 0x4c, 0xae, 0xf5, 0x23, 0x58, 0x95, 0x5a, + 0x74, 0x2e, 0x1e, 0x5b, 0x9e, 0xe5, 0xdb, 0xaa, 0x3b, 0x7e, 0xb4, 0xec, 0x08, 0x89, 0x97, 0x29, + 0x01, 0xa6, 0xad, 0x7f, 0x0d, 0x35, 0xb1, 0x14, 0xed, 0x07, 0x11, 0xa1, 0x83, 0x95, 0x85, 0x51, + 0x39, 0x58, 0x55, 0x28, 0x45, 0x30, 0x43, 0x65, 0x64, 0x0d, 0x53, 0xca, 0xd3, 0x6c, 0xc3, 0xe8, + 0xd3, 0x8c, 0xae, 0xda, 0xfa, 0xbf, 0x6b, 0xd0, 0xc8, 0xbc, 0x69, 0x2d, 0x3c, 0x39, 0x67, 0xd6, + 0xbd, 0x52, 0xc1, 0xba, 0xa7, 0xde, 0xdd, 0x54, 0x45, 0x8a, 0xbd, 0x07, 0x35, 0xe9, 0x52, 0x37, + 0x54, 0xa5, 0x3d, 0x41, 0x1a, 0x84, 0xec, 0x84, 0x9d, 0xf1, 0x84, 0x4a, 0x8e, 0xcd, 0x34, 0x79, + 0x10, 0xd2, 0x04, 0xa8, 0x1c, 0x4d, 0xa1, 0x78, 0xa5, 0xaf, 0x26, 0x69, 0x14, 0x6b, 0x1d, 0x66, + 0xd3, 0xd7, 0xe6, 0x28, 0xbb, 0xac, 0xb3, 0xb2, 0x2f, 0x17, 0xd0, 0x7b, 0x6a, 0xb4, 0xa9, 0x59, + 0xfb, 0x56, 0xa3, 0x7d, 0xb4, 0x0e, 0x55, 0x75, 0x90, 0x42, 0x73, 0x30, 0xdd, 0xdb, 0xfd, 0xba, + 0x3d, 0x85, 0x2a, 0x30, 0x33, 0xd8, 0x3f, 0xda, 0x6c, 0xcf, 0x88, 0x5f, 0xdd, 0x76, 0xf9, 0xd1, + 0x1f, 0x69, 0x50, 0x55, 0x4b, 0x0f, 0x6a, 0x40, 0x75, 0x6b, 0xd0, 0x37, 0xcc, 0xc1, 0xee, 0xa7, + 0x7b, 0xed, 0x29, 0x34, 0x0f, 0x2d, 0x63, 0xfb, 0xd5, 0xde, 0xe1, 0xb6, 0xf9, 0xd5, 0x9e, 0xf1, + 0xc5, 0xcb, 0xbd, 0x5e, 0xbf, 0xad, 0xa1, 0x16, 0xd4, 0x04, 0x71, 0x67, 0xef, 0xe0, 0xb0, 0x5d, + 0x42, 0x08, 0x9a, 0x2f, 0xf7, 0xb6, 0x7a, 0x2f, 0x13, 0xa1, 0x69, 0xd4, 0x04, 0xe0, 0x34, 0x26, + 0x33, 0x83, 0x6e, 0x41, 0x43, 0x28, 0x1d, 0x7e, 0xb9, 0xbb, 0xbb, 0xfd, 0xb2, 0x3d, 0x8b, 0xda, + 0x50, 0xe7, 0x22, 0x82, 0x52, 0x7e, 0xf4, 0x1c, 0x20, 0x59, 0xd7, 0xa8, 0x8d, 0xbb, 0x7b, 0xbb, + 0xdb, 0xed, 0x29, 0x54, 0x87, 0xca, 0xee, 0x9e, 0xb9, 0xbd, 0xbb, 0xd5, 0xdb, 0x6f, 0x6b, 0xa8, + 0x0a, 0xb3, 0x2c, 0xc1, 0xb5, 0x4b, 0x7c, 0x18, 0x83, 0xfd, 0xf6, 0xf4, 0xc6, 0x27, 0x00, 0xfc, + 0xb1, 0x09, 0xfb, 0xef, 0xab, 0x27, 0x30, 0xc3, 0xfe, 0x2a, 0x27, 0x27, 0xff, 0xd3, 0xb5, 0x2a, + 0x69, 0xa9, 0xff, 0xeb, 0x7a, 0xa2, 0xbd, 0x58, 0xfe, 0xc5, 0xb7, 0x6b, 0xda, 0x3f, 0x7c, 0xbb, + 0xa6, 0xfd, 0xcb, 0xb7, 0x6b, 0xda, 0x9f, 0xfe, 0xeb, 0xda, 0xd4, 0x4f, 0x66, 0xd9, 0x65, 0xfb, + 0x71, 0x99, 0xfd, 0xf9, 0xe8, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x30, 0x8b, 0xfe, 0xdc, 0x35, + 0x36, 0x00, 0x00, } diff --git a/felix/proto/felixbackend.proto b/felix/proto/felixbackend.proto index 1f79560bd57..a6e5dd46dda 100644 --- a/felix/proto/felixbackend.proto +++ b/felix/proto/felixbackend.proto @@ -437,6 +437,7 @@ message TierInfo { string name = 1; repeated string ingress_policies = 2; repeated string egress_policies = 3; + string default_action = 4; } message NatInfo { @@ -668,7 +669,7 @@ message ServiceUpdate { string name = 1; string namespace = 2; string type = 3; - string cluster_ip = 4; + repeated string cluster_ips = 4; string loadbalancer_ip = 5; repeated string external_ips = 6; repeated ServicePort ports = 7; diff --git a/felix/routetable/.gitattributes b/felix/routetable/.gitattributes new file mode 100644 index 00000000000..aa312741eaf --- /dev/null +++ b/felix/routetable/.gitattributes @@ -0,0 +1 @@ +routeclass_string.go linguist-generated=true diff --git a/felix/routetable/bench_test.go b/felix/routetable/bench_test.go new file mode 100644 index 00000000000..85835f8ed8c --- /dev/null +++ b/felix/routetable/bench_test.go @@ -0,0 +1,129 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package routetable_test + +import ( + "fmt" + "math/rand" + "os" + "runtime" + "testing" + "time" + + . "github.com/onsi/gomega" + "github.com/prometheus/procfs" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" + + "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs" + "github.com/projectcalico/calico/felix/fv/utils" + "github.com/projectcalico/calico/felix/ip" + "github.com/projectcalico/calico/felix/logutils" + mocknetlink "github.com/projectcalico/calico/felix/netlinkshim/mocknetlink" + . "github.com/projectcalico/calico/felix/routetable" + "github.com/projectcalico/calico/felix/routetable/ownershippol" +) + +// Note: these benchmarks must be run as root, because they create a dummy +// interface. + +func BenchmarkResync1024(b *testing.B) { + benchResyncNumRoutes(b, 1024) +} +func BenchmarkResync4096(b *testing.B) { + benchResyncNumRoutes(b, 4096) +} +func BenchmarkResync65536(b *testing.B) { + benchResyncNumRoutes(b, 65536) +} + +func benchResyncNumRoutes(b *testing.B, numRoutes int) { + RegisterTestingT(b) + + if os.Getuid() != 0 { + b.Fatal("This test must be run as root.") + } + + logutils.ConfigureEarlyLogging() + logrus.SetLevel(logrus.WarnLevel) + + ifaceName := fmt.Sprintf("testcali%04x", rand.Intn(65536)) + utils.Run("ip", "link", "add", "name", ifaceName, "type", "dummy") + b.Cleanup(func() { + utils.Run("ip", "link", "del", "dev", ifaceName) + }) + utils.Run("ip", "link", "set", "dev", ifaceName, "up") + + sum := logutils.NewSummarizer("test") + mockDP := mocknetlink.New() + rt := New( + ownershippol.NewMainTable( + dataplanedefs.VXLANIfaceNameV4, + 88, + []string{"testcali"}, + false, + ), + 4, + 5*time.Second, + nil, + 88, + false, + unix.RT_TABLE_MAIN, + sum, + mockDP, + ) + + n := 0 +outer: + for i := 0; i < 256; i++ { + for j := 0; j < 256; j++ { + rt.RouteUpdate(RouteClassLocalWorkload, ifaceName, Target{ + CIDR: ip.MustParseCIDROrIP(fmt.Sprintf("10.0.%d.%d/32", i, j)), + }) + n++ + if n == numRoutes { + break outer + } + } + } + if n < numRoutes { + b.Fatalf("Only added %d routes", n) + } + err := rt.Apply() + if err != nil { + b.Fatal(err) + } + + b.ReportAllocs() + + proc, _ := procfs.NewProc(os.Getpid()) + stat, _ := proc.Stat() + startCPU := stat.CPUTime() + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + rt.QueueResync() + err := rt.Apply() + if err != nil { + b.Fatal(err) + } + } + + runtime.GC() + stat, _ = proc.Stat() + endCPU := stat.CPUTime() + b.ReportMetric((endCPU-startCPU)/float64(b.N)*1000000000, "ncpu/op") +} diff --git a/felix/routetable/conntrack_owner_tracker.go b/felix/routetable/conntrack_owner_tracker.go new file mode 100644 index 00000000000..06d97fb0857 --- /dev/null +++ b/felix/routetable/conntrack_owner_tracker.go @@ -0,0 +1,327 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package routetable + +import ( + "time" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/felix/deltatracker" + "github.com/projectcalico/calico/felix/ip" + "github.com/projectcalico/calico/libcalico-go/lib/set" +) + +type RouteOwnershipTracker interface { + UpdateCIDROwner(addr ip.CIDR, ifaceIdx int, routeClass RouteClass) + RemoveCIDROwner(addr ip.CIDR) + + CIDRNeedsEarlyCleanup(cidr ip.CIDR, oldIface int) bool + OnDataplaneRouteDeleted(cidr ip.CIDR, ifindex int) + StartConntrackCleanupAndReset() + + WaitForPendingDeletion(cidr ip.CIDR) +} + +type conntrackOwner struct { + ifaceIdx int + routeClass RouteClass +} + +// ConntrackCleanupManager handles cleaning up conntrack entries on behalf of +// a RouteTable when routes are moved or deleted . It: +// +// - Uses a DeltaTracker to track which interfaces the RouteTable has +// told us own which IP addresses. We assume that the RouteTable only +// allows one route per CIDR (even though it understands how to clean up +// routes for other ToS and priority values). +// +// - Expects a callback from the RouteTable when a route is deleted. +// +// - Uses the interface index and route class on that callback to decide +// if the route being deleted needs a conntrack cleanup. +// +// - Provides a lookup function to check if an updated route needs a cleanup. +// +// - Updates that don't change the interface index don't need cleanup. +// +// - Updates from remote to remote don't need cleanup. For example, a route +// moving from VXLAN to VXLAN-same-subnet. +// +// - Updates where there was no previous route don't need cleanup. +// +// A complicating factor is that the kernel keys routes using CIDR, ToS and +// priority whereas conntrack entries are keyed on 5-tuple only. We sidestep +// that by assuming the RouteTable only allows one route per CIDR in its final +// state. [Shaun] I tried to handle multiple routes per CIDR, but the +// complexity spiralled, and it wasn't clear what should be done in a lot of +// the corner cases. I'm hoping that, should we add function that uses multiple +// ToSes or priorities, the right way to handle conflicts will be clear at that +// time! +type ConntrackCleanupManager struct { + ipVersion uint8 + + // addrOwners tracks which interfaces own which IP addresses. We update + // the Desired() side immediately as the RouteTable gives us update. The + // Dataplane() side is updated to record the "previous state" as soon as + // we've started conntrack cleanups. + addrOwners *deltatracker.DeltaTracker[ip.Addr, conntrackOwner] + + // addrsToCleanUp tracks which IP addresses need conntrack cleanup. We + // don't start the cleanup immediately in case there are multiple routes + // with the same CIDR being deleted by the RouteTable. + addrsToCleanUp set.Set[ip.Addr] + + // perIPDoneChans contains a channel for the most recent conntrack cleanup + // for a given IP. This allows us to block until the cleanup is done. + perIPDoneChans map[ip.Addr]chan struct{} + // cleanupDoneC is used to manage cleanup of the entries in perIPDoneChans. + // The background goroutine sends the IP address that it cleaned up on this + // channel after it closes its individual "done" channel. + cleanupDoneC chan ip.Addr + + conntrack conntrackIface +} + +var _ RouteOwnershipTracker = (*ConntrackCleanupManager)(nil) + +func NewConntrackCleanupManager(ipVersion uint8, conntrack conntrackIface) *ConntrackCleanupManager { + return &ConntrackCleanupManager{ + ipVersion: ipVersion, + addrOwners: deltatracker.New[ip.Addr, conntrackOwner]( + deltatracker.WithValuesEqualFn[ip.Addr, conntrackOwner](func(a, b conntrackOwner) bool { + return a == b + }), + ), + addrsToCleanUp: set.New[ip.Addr](), + perIPDoneChans: map[ip.Addr]chan struct{}{}, + cleanupDoneC: make(chan ip.Addr), + conntrack: conntrack, + } +} + +// UpdateCIDROwner is called when the new owner of a CIDR is calculated. +// It updates the "desired" next state, so multiple calls for the same CIDR +// are effectively coalesced; only the most recent update is remembered. +// the actual cleanup is triggered later by calls to OnDataplaneRouteDeleted and +// StartConntrackCleanupAndReset. +func (c *ConntrackCleanupManager) UpdateCIDROwner(cidr ip.CIDR, ifaceIdx int, routeClass RouteClass) { + // We can't currently handle non-32-bit IPv4 or non-128-bit IPv6 CIDRs. + // To do so, we'd need to handle longest-prefix match. + if !cidr.IsSingleAddress() { + return + } + c.addrOwners.Desired().Set(cidr.Addr(), conntrackOwner{ifaceIdx: ifaceIdx, routeClass: routeClass}) +} + +// RemoveCIDROwner is called when there is no longer an owner for the given +// CIDR. Like UpdateCIDROwner, it updates the "desired" next state so +// a call to UpdateCIDROwner for the same CIDR before the cleanup is triggered +// will undo the removal. +func (c *ConntrackCleanupManager) RemoveCIDROwner(cidr ip.CIDR) { + c.addrOwners.Desired().Delete(cidr.Addr()) +} + +// OnDataplaneRouteDeleted is called when the RouteTable tells us that a route +// has been removed from the dataplane on the given interface. In most cases, +// this will queue the CIDR for conntrack cleanup at the next call to +// StartConntrackCleanupAndReset. +// +// No cleanup is triggered if there is a desired route for the given CIDR +// and that desired route is staying on this interface. +func (c *ConntrackCleanupManager) OnDataplaneRouteDeleted(cidr ip.CIDR, ifindex int) { + if !cidr.IsSingleAddress() { + return + } + addr := cidr.Addr() + desiredRoute, desiredExists := c.addrOwners.Desired().Get(addr) + + if desiredExists { + // RouteTable is going to replace this route with another one. + if desiredRoute.ifaceIdx == ifindex { + // Route isn't actually moving, just a ToS/priority update? + logrus.WithField("ip", addr).Debug( + "Route staying on same interface, ignoring.") + return + } + previousRoute, _ := c.addrOwners.Dataplane().Get(addr) + if previousRoute.ifaceIdx == desiredRoute.ifaceIdx { + // We've already processed this route in a previous round so the + // RouteTable must be deleting a stray newly added route. + // Not safe to clean up conntrack entries. + logrus.WithField("ip", addr).Info( + "Route deleted but tracker shows we've already programmed correct route, ignoring.") + return + } + } + logrus.WithField("ip", addr).Debug("Route deleted, queueing conntrack deletion.") + c.addrsToCleanUp.Add(addr) +} + +// CIDRNeedsEarlyCleanup is called by the RouteTable to check if a route should +// be deleted early, to allow for conntrack cleanup to be properly sequenced. +func (c *ConntrackCleanupManager) CIDRNeedsEarlyCleanup(cidr ip.CIDR, oldIface int) bool { + if !cidr.IsSingleAddress() { + return false + } + addr := cidr.Addr() + desiredRoute, desiredExists := c.addrOwners.Desired().Get(addr) + dataplaneRoute, dataplaneExists := c.addrOwners.Dataplane().Get(addr) + if dataplaneExists && desiredExists && desiredRoute.ifaceIdx == dataplaneRoute.ifaceIdx { + // The desired route is already in place from a previous run so this + // route must be some sort of stray route being cleaned up after the + // fact. We don't want to kill conntrack for the already-programmed + // good route. + logrus.WithField("ip", addr).Debug("Dataplane already has correct route, not cleaning up.") + return false + } + if desiredExists && desiredRoute.ifaceIdx == oldIface { + // Route isn't actually moving, just a ToS/priority update? + logrus.WithField("ip", addr).Debug("Route staying on same iface, no need to clean up.") + return false + } + if desiredRoute.routeClass.IsRemote() && dataplaneRoute.routeClass.IsRemote() { + // Moving between different kinds of tunnel, not safe to clean up, it + // may still be same remote workload. + logrus.WithField("ip", addr).Debug("Route moving from remote->remote, skipping cleanup.") + return false + } + logrus.WithField("ip", addr).Debug("Address needs cleanup.") + return true +} + +// StartConntrackCleanupAndReset starts all pending conntrack cleanups and +// resets the tracker to prepare for the next round of updates. +func (c *ConntrackCleanupManager) StartConntrackCleanupAndReset() { + c.addrsToCleanUp.Iter(func(addr ip.Addr) error { + c.startDeletion(addr) + return set.RemoveItem + }) + + // Reset the tracker; we assume that the RouteTable has now implemented + // its planned actions, and it'll tell us if any routes change. + c.addrOwners.PendingDeletions().Iter(func(_ ip.Addr) deltatracker.IterAction { + return deltatracker.IterActionUpdateDataplane + }) + c.addrOwners.PendingUpdates().Iter(func(_ ip.Addr, _ conntrackOwner) deltatracker.IterAction { + return deltatracker.IterActionUpdateDataplane + }) + c.cleanUpStaleChannels() +} + +// startDeletion starts the deletion of conntrack entries for the given CIDR in the background. Pending +// deletions are tracked in the perIPDoneChans map so we can block waiting for them later. +// +// It's important to do the conntrack deletions in the background because scanning the conntrack +// table is very slow if there are a lot of entries. Previously, we did the deletion synchronously +// but that led to lengthy Apply() calls on the critical path. +func (c *ConntrackCleanupManager) startDeletion(ipAddr ip.Addr) { + logrus.WithField("ip", ipAddr).Debug("Starting goroutine to delete conntrack entries") + done := make(chan struct{}) + c.perIPDoneChans[ipAddr] = done + go func() { + defer func() { + c.cleanupDoneC <- ipAddr + }() + defer close(done) + c.conntrack.RemoveConntrackFlows(c.ipVersion, ipAddr.AsNetIP()) + logrus.WithField("ip", ipAddr).Debug("Deleted conntrack entries") + }() +} + +// DoPeriodicCleanup scans the perIPDoneChans map for completed entries and removes them. +func (c *ConntrackCleanupManager) cleanUpStaleChannels() { + for { + select { + case ipAddr := <-c.cleanupDoneC: + c.cleanUpExpiredChan(ipAddr) + default: + return + } + } +} + +func (c *ConntrackCleanupManager) cleanUpExpiredChan(ipAddr ip.Addr) { + ch := c.perIPDoneChans[ipAddr] + select { + case <-ch: + logrus.WithField("ip", ipAddr).Debug( + "Background goroutine finished deleting conntrack entries") + delete(c.perIPDoneChans, ipAddr) + default: + // Can get here if there was >1 deletion started for the same IP. + logrus.WithField("ip", ipAddr).Debug( + "Background goroutine yet to finish deleting conntrack entries") + } +} + +// WaitForPendingDeletion waits for any pending conntrack deletions (if any) +// for the given IP to complete. Returns immediately if there's no pending +// deletion. +func (c *ConntrackCleanupManager) WaitForPendingDeletion(cidr ip.CIDR) { + if !cidr.IsSingleAddress() { + return + } + ipAddr := cidr.Addr() + ch, ok := c.perIPDoneChans[ipAddr] + if !ok { + conntrackBlockTimeSummary.Observe(0) + return + } + // Do a non-blocking read first, to avoid logging a message if the deletion has already + // completed. + startTime := time.Now() + select { + case <-ch: + goto done + default: + logrus.WithField("ip", ipAddr).Info("Need to wait for pending conntrack deletion to finish...") + } + for { + select { + case <-ch: + logrus.WithFields(logrus.Fields{ + "ip": ipAddr, + "timeWaiting": time.Since(startTime), + }).Info("Done waiting for pending conntrack deletion to finish") + goto done + case <-time.After(10 * time.Second): + logrus.WithFields(logrus.Fields{ + "ip": ipAddr, + "timeWaiting": time.Since(startTime), + }).Info("Still waiting for pending conntrack deletion to finish...") + } + } +done: + delete(c.perIPDoneChans, ipAddr) + conntrackBlockTimeSummary.Observe(time.Since(startTime).Seconds()) +} + +// NoOpRouteTracker is a dummy implementation of RouteOwnershipTracker that does nothing. +type NoOpRouteTracker struct { +} + +func NewNoOpRouteTracker() NoOpRouteTracker { + return NoOpRouteTracker{} +} + +func (n NoOpRouteTracker) UpdateCIDROwner(addr ip.CIDR, ifaceIdx int, routeClass RouteClass) {} +func (n NoOpRouteTracker) RemoveCIDROwner(addr ip.CIDR) {} +func (n NoOpRouteTracker) OnDataplaneRouteDeleted(cidr ip.CIDR, ifindex int) {} +func (n NoOpRouteTracker) CIDRNeedsEarlyCleanup(cidr ip.CIDR, ifindex int) bool { return false } +func (n NoOpRouteTracker) StartConntrackCleanupAndReset() {} +func (n NoOpRouteTracker) WaitForPendingDeletion(cidr ip.CIDR) {} + +var _ RouteOwnershipTracker = (*NoOpRouteTracker)(nil) diff --git a/felix/routetable/conntrack_owner_tracker_test.go b/felix/routetable/conntrack_owner_tracker_test.go new file mode 100644 index 00000000000..25cea88bc20 --- /dev/null +++ b/felix/routetable/conntrack_owner_tracker_test.go @@ -0,0 +1,266 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package routetable + +import ( + "context" + "fmt" + "net" + "sync" + "testing" + "time" + + . "github.com/onsi/gomega" + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/felix/ip" +) + +var ( + cidr1 = ip.MustParseCIDROrIP("10.0.0.1") +) + +func TestConntrackCleanupManager_NewRoute(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // Call methods in the same order as the RouteTable would. + + // Set the new owner for a previously-unknown IP. + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassLocalWorkload) + + h.ccm.StartConntrackCleanupAndReset() + + Consistently(h.conntrack.NumPendingRemovals, "10ms").Should(Equal(0)) + expectWaitForPendingDeletionToReturnImmediately(h.ccm, cidr1) + + expectInSyncAtEnd(h.ccm) +} + +func TestConntrackCleanupManager_MovedRoute(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // Call methods in the same order as the RouteTable would. + + // Initially, the route is owned by interface 10. + t.Log("Setting initial owner.") + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassLocalWorkload) + // Commit that change. + h.ccm.StartConntrackCleanupAndReset() + + // Then, the exact same route moves to interface 11. + t.Log("Setting new owner.") + h.ccm.UpdateCIDROwner(cidr1, 11, RouteClassLocalWorkload) + + // RouteTable won't have any deletions to do, so move on to the first + // pass over the updated routes. + Expect(h.ccm.CIDRNeedsEarlyCleanup(cidr1, 10)).To(BeTrue(), + "Moved CIDR should need cleanup.") + // RouteTable tells us that it deleted the old route. + h.ccm.OnDataplaneRouteDeleted(cidr1, 10) + + // Then, asks us to clean up conntrack. + h.ccm.StartConntrackCleanupAndReset() + Eventually(h.conntrack.NumPendingRemovals).Should(Equal(1), + "Expected one pending removal after moving route.") + expectWaitForPendingDeletionToDelay(h.ccm, h.conntrack, cidr1) + + expectInSyncAtEnd(h.ccm) +} +func TestConntrackCleanupManager_MovedRouteRemoteToRemote(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // Call methods in the same order as the RouteTable would. + + // Initially, the route is owned by interface 10. + t.Log("Setting initial owner.") + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassVXLANTunnel) + // Commit that change. + h.ccm.StartConntrackCleanupAndReset() + + // Then, the exact same route moves to interface 11. + t.Log("Setting new owner.") + h.ccm.UpdateCIDROwner(cidr1, 11, RouteClassVXLANSameSubnet) + + // RouteTable won't have any deletions to do, so move on to the first + // pass over the updated routes. + Expect(h.ccm.CIDRNeedsEarlyCleanup(cidr1, 10)).To(BeFalse(), + "Remote to remote moves houldn't trigger cleanup.") + + h.ccm.StartConntrackCleanupAndReset() + Consistently(h.conntrack.NumPendingRemovals, "10ms").Should(Equal(0)) + expectWaitForPendingDeletionToReturnImmediately(h.ccm, cidr1) + + expectInSyncAtEnd(h.ccm) +} + +func TestConntrackCleanupManager_ChangeOfPrioritySameInterface(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // This mimics what happens if the CNI plugin adds a route with one priority + // and then Felix updates it to a different priority. + t.Log("Setting initial owner.") + + // RouteTable spots the p=100 route, but it just queues it up for deletion. + // Meanwhile, it tells us about the route it wants to program. + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassLocalWorkload) + // Then the deletion. + h.ccm.OnDataplaneRouteDeleted(cidr1, 10) + // Which should be ignored due to the prior update to signal intent to + // create that route. + Expect(h.ccm.CIDRNeedsEarlyCleanup(cidr1, 10)).To(BeFalse(), + "CIDR on same interface should not need cleanup.") + + h.ccm.StartConntrackCleanupAndReset() + Consistently(h.conntrack.NumPendingRemovals, "10ms").Should(Equal(0)) + expectWaitForPendingDeletionToReturnImmediately(h.ccm, cidr1) + + expectInSyncAtEnd(h.ccm) +} + +func TestConntrackCleanupManager_ChangeOfPriorityDifferentInterface(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // This mimics what happens if the CNI plugin adds a route with one priority + // and then Felix updates it to a different priority. + t.Log("Setting initial owner.") + + // RouteTable spots the p=100 route, but it just queues it up for deletion. + // Meanwhile, it tells us about the route it wants to program. + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassLocalWorkload) + // Then the deletion on a different interface. + h.ccm.OnDataplaneRouteDeleted(cidr1, 11) + + h.ccm.StartConntrackCleanupAndReset() + Eventually(h.conntrack.NumPendingRemovals).Should(Equal(1)) + expectWaitForPendingDeletionToDelay(h.ccm, h.conntrack, cidr1) + + expectInSyncAtEnd(h.ccm) +} + +func TestConntrackCleanupManager_DeletedRoute(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // Tell the CCM about the route. + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassLocalWorkload) + h.ccm.StartConntrackCleanupAndReset() // Commit to the delta tracker. + Consistently(h.conntrack.NumPendingRemovals, "10ms").Should(Equal(0)) + + // Then, the route is deleted. + h.ccm.RemoveCIDROwner(cidr1) + h.ccm.OnDataplaneRouteDeleted(cidr1, 10) + h.ccm.StartConntrackCleanupAndReset() + Eventually(h.conntrack.NumPendingRemovals).Should(Equal(1)) + expectWaitForPendingDeletionToDelay(h.ccm, h.conntrack, cidr1) +} + +func TestConntrackCleanupManager_DeletedStaleRoute(t *testing.T) { + h := setupConntrackTrackerTest(t) + + // Tell the CCM about the route. + h.ccm.UpdateCIDROwner(cidr1, 10, RouteClassLocalWorkload) + h.ccm.StartConntrackCleanupAndReset() // Commit to the delta tracker. + Consistently(h.conntrack.NumPendingRemovals, "10ms").Should(Equal(0)) + + // Then, the route is deleted from a different interface. + h.ccm.OnDataplaneRouteDeleted(cidr1, 11) + h.ccm.StartConntrackCleanupAndReset() + Consistently(h.conntrack.NumPendingRemovals, "10ms").Should(Equal(0)) +} + +type conntrackTrackerHarness struct { + ccm *ConntrackCleanupManager + conntrack *mockConntrack +} + +func setupConntrackTrackerTest(t *testing.T) *conntrackTrackerHarness { + RegisterTestingT(t) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + conntrack := newMockConntrack(ctx) + ccm := NewConntrackCleanupManager(4, conntrack) + t.Cleanup(cancel) + return &conntrackTrackerHarness{ccm, conntrack} +} + +func expectWaitForPendingDeletionToReturnImmediately(ccm *ConntrackCleanupManager, cidr ip.CIDR) { + delStart := time.Now() + ccm.WaitForPendingDeletion(cidr) + ExpectWithOffset(1, time.Since(delStart)).To(BeNumerically("<", 10*time.Millisecond), + fmt.Sprintf("WaitForPendingDeletion(%v) should return immediately.", cidr)) +} + +func expectWaitForPendingDeletionToDelay(ccm *ConntrackCleanupManager, conntrack *mockConntrack, cidr ip.CIDR) { + delStart := time.Now() + go func() { + time.Sleep(10 * time.Millisecond) + conntrack.SignalPendingDeletionComplete(cidr.Addr()) + }() + ccm.WaitForPendingDeletion(cidr) + delay := time.Since(delStart) + ExpectWithOffset(1, delay).To(BeNumerically(">=", 10*time.Millisecond), + fmt.Sprintf("WaitForPendingDeletion(%v) should return after 10ms.", cidr)) + ExpectWithOffset(1, delay).To(BeNumerically("<", 20*time.Millisecond), + fmt.Sprintf("WaitForPendingDeletion(%v) should return before 20ms.", cidr)) +} + +func expectInSyncAtEnd(ccm *ConntrackCleanupManager) { + ExpectWithOffset(1, ccm.addrOwners.InSync()).To(BeTrue(), "Expected delta tracker to be in sync at end of test.") + ExpectWithOffset(1, ccm.addrsToCleanUp).To(BeEmpty(), "Leaked addresses in addrsToCleanUp?") +} + +type mockConntrack struct { + lock sync.Mutex + + pendingRemovals map[ip.Addr]context.CancelFunc + baseCtx context.Context +} + +func newMockConntrack(baseCtx context.Context) *mockConntrack { + return &mockConntrack{ + pendingRemovals: map[ip.Addr]context.CancelFunc{}, + baseCtx: baseCtx, + } +} + +func (m *mockConntrack) NumPendingRemovals() int { + m.lock.Lock() + defer m.lock.Unlock() + return len(m.pendingRemovals) +} + +// RemoveConntrackFlows is a called by background goroutine. It blocks until +// the foreground test code signals that the fake removal is complete. +func (m *mockConntrack) RemoveConntrackFlows(ipVersion uint8, ipAddr net.IP) { + logCtx := logrus.WithFields(logrus.Fields{ + "ipVersion": ipVersion, + "ipAddr": ipAddr, + }) + logCtx.Info("RemoveConntrackFlows called.") + addr := ip.FromNetIP(ipAddr) + ctx, cancel := context.WithCancel(m.baseCtx) + m.lock.Lock() + m.pendingRemovals[addr] = cancel + m.lock.Unlock() + + logCtx.Info("RemoveConntrackFlows waiting for signal to return...") + <-ctx.Done() + logCtx.Info("RemoveConntrackFlows returning") +} + +func (m *mockConntrack) SignalPendingDeletionComplete(addr ip.Addr) { + m.lock.Lock() + defer m.lock.Unlock() + m.pendingRemovals[addr]() + delete(m.pendingRemovals, addr) +} diff --git a/felix/routetable/dataplane_shims.go b/felix/routetable/dataplane_shims.go index 7d8bd247bca..f3661a677b2 100644 --- a/felix/routetable/dataplane_shims.go +++ b/felix/routetable/dataplane_shims.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2017,2019-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,18 +16,8 @@ package routetable import ( "net" - "os/exec" - - "github.com/projectcalico/calico/felix/ip" ) type conntrackIface interface { RemoveConntrackFlows(ipVersion uint8, ipAddr net.IP) } - -func addStaticARPEntry(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) error { - cmd := exec.Command("arp", - "-s", cidr.Addr().String(), destMAC.String(), - "-i", ifaceName) - return cmd.Run() -} diff --git a/felix/routetable/defs.go b/felix/routetable/defs.go new file mode 100644 index 00000000000..094203e5908 --- /dev/null +++ b/felix/routetable/defs.go @@ -0,0 +1,154 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package routetable + +import ( + "errors" + "net" + "reflect" + + "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" + + "github.com/projectcalico/calico/felix/ip" +) + +//go:generate stringer -type=RouteClass + +// RouteClass is a type used to identify the different groups of routes +// that we program. It is used as a tie-breaker when there are conflicting +// routes for the same CIDR (lowest numeric value wins). +type RouteClass int + +const ( + RouteClassLocalWorkload RouteClass = iota + RouteClassBPFSpecial + RouteClassWireguard + RouteClassVXLANSameSubnet + RouteClassVXLANTunnel + RouteClassIPAMBlockDrop + + RouteClassMax +) + +func (c RouteClass) IsRemote() bool { + switch c { + case RouteClassVXLANTunnel, RouteClassVXLANSameSubnet, RouteClassWireguard: + return true + default: + return false + } +} + +const ( + // Use this for targets with no outbound interface. + InterfaceNone = "*NoOIF*" +) + +var ( + ConnectFailed = errors.New("connect to netlink failed") + ListFailed = errors.New("netlink list operation failed") + UpdateFailed = errors.New("netlink update operation failed") + IfaceNotPresent = errors.New("interface not present") + IfaceDown = errors.New("interface down") +) + +type Target struct { + Type TargetType + CIDR ip.CIDR + GW ip.Addr + Src ip.Addr + DestMAC net.HardwareAddr + Protocol netlink.RouteProtocol + MultiPath []NextHop +} + +func (t Target) Equal(t2 Target) bool { + return reflect.DeepEqual(t, t2) +} + +func (t Target) RouteType() int { + switch t.Type { + case TargetTypeLocal: + return unix.RTN_LOCAL + case TargetTypeThrow: + return unix.RTN_THROW + case TargetTypeBlackhole: + return unix.RTN_BLACKHOLE + case TargetTypeProhibit: + return unix.RTN_PROHIBIT + case TargetTypeUnreachable: + return unix.RTN_UNREACHABLE + default: + return unix.RTN_UNICAST + } +} + +func (t Target) RouteScope() netlink.Scope { + switch t.Type { + case TargetTypeLocal: + return netlink.SCOPE_HOST + case TargetTypeLinkLocalUnicast: + return netlink.SCOPE_LINK + case TargetTypeGlobalUnicast: + return netlink.SCOPE_UNIVERSE + case TargetTypeNoEncap: + return netlink.SCOPE_UNIVERSE + case TargetTypeVXLAN: + return netlink.SCOPE_UNIVERSE + case TargetTypeThrow: + return netlink.SCOPE_UNIVERSE + case TargetTypeBlackhole: + return netlink.SCOPE_UNIVERSE + case TargetTypeProhibit: + return netlink.SCOPE_UNIVERSE + case TargetTypeOnLink: + return netlink.SCOPE_LINK + default: + return netlink.SCOPE_LINK + } +} + +func (t Target) Flags() netlink.NextHopFlag { + switch t.Type { + case TargetTypeVXLAN, TargetTypeNoEncap, TargetTypeOnLink: + return unix.RTNH_F_ONLINK + default: + return 0 + } +} + +type NextHop struct { + Gw ip.Addr + IfaceName string +} + +type TargetType string + +const ( + TargetTypeLocal TargetType = "local" + TargetTypeVXLAN TargetType = "vxlan" + TargetTypeNoEncap TargetType = "noencap" + TargetTypeOnLink TargetType = "onlink" + TargetTypeGlobalUnicast TargetType = "global-unicast" + TargetTypeLinkLocalUnicast TargetType = "local-unicast" + + // The following target types should be used with InterfaceNone. + + TargetTypeBlackhole TargetType = "blackhole" + TargetTypeProhibit TargetType = "prohibit" + TargetTypeThrow TargetType = "throw" + TargetTypeUnreachable TargetType = "unreachable" +) diff --git a/felix/routetable/dummy_table.go b/felix/routetable/dummy_table.go index 134c275cd3e..9701432d12a 100644 --- a/felix/routetable/dummy_table.go +++ b/felix/routetable/dummy_table.go @@ -8,21 +8,35 @@ import ( type DummyTable struct { } -func (_ *DummyTable) OnIfaceStateChanged(_ string, _ ifacemonitor.State) { +func (_ *DummyTable) OnIfaceStateChanged(_ string, _ int, _ ifacemonitor.State) { } func (_ *DummyTable) QueueResync() { } +func (_ *DummyTable) QueueResyncIface(string) { +} + func (_ *DummyTable) Apply() error { return nil } -func (_ *DummyTable) SetRoutes(_ string, _ []Target) { +func (_ *DummyTable) SetRoutes(routeClass RouteClass, ifaceName string, targets []Target) { +} + +func (_ *DummyTable) RouteRemove(routeClass RouteClass, ifaceName string, cidr ip.CIDR) { +} + +func (_ *DummyTable) RouteUpdate(routeClass RouteClass, ifaceName string, target Target) { +} + +func (_ *DummyTable) Index() int { + return 0 } -func (_ *DummyTable) RouteRemove(_ string, _ ip.CIDR) { +func (_ *DummyTable) ReadRoutesFromKernel(ifaceName string) ([]Target, error) { + return nil, nil } -func (_ *DummyTable) RouteUpdate(_ string, _ Target) { +func (_ *DummyTable) SetRemoveExternalRoutes(b bool) { } diff --git a/felix/routetable/interface.go b/felix/routetable/interface.go index debd32911cb..1f5c6bc4500 100644 --- a/felix/routetable/interface.go +++ b/felix/routetable/interface.go @@ -19,18 +19,73 @@ import ( "github.com/projectcalico/calico/felix/ip" ) -// RouteTableSyncer is the interface used to manage data-sync of route table managers. This includes notification of +// SyncerInterface is the interface used to manage data-sync of route table managers. This includes notification of // interface state changes, hooks to queue a full resync and apply routing updates. -type RouteTableSyncer interface { - OnIfaceStateChanged(string, ifacemonitor.State) +type SyncerInterface interface { + OnIfaceStateChanged(name string, ifIndex int, state ifacemonitor.State) QueueResync() Apply() error } -// RouteTable is the interface provided by the standard routetable module used to program the RIB. -type RouteTableInterface interface { - RouteTableSyncer - SetRoutes(ifaceName string, targets []Target) - RouteRemove(ifaceName string, cidr ip.CIDR) - RouteUpdate(ifaceName string, target Target) +// Interface is the interface provided by the standard routetable module used to program the RIB. +type Interface interface { + SyncerInterface + SetRoutes(routeClass RouteClass, ifaceName string, targets []Target) + RouteRemove(routeClass RouteClass, ifaceName string, cidr ip.CIDR) + RouteUpdate(routeClass RouteClass, ifaceName string, target Target) + Index() int + QueueResyncIface(ifaceName string) + ReadRoutesFromKernel(ifaceName string) ([]Target, error) } + +// ClassView wraps a RouteTable with a simplified API that removes the need to +// pass the RouteClass to each method. +type ClassView struct { + class RouteClass + routeTable Interface +} + +func NewClassView(class RouteClass, routeTable Interface) *ClassView { + return &ClassView{ + class: class, + routeTable: routeTable, + } +} + +func (cv *ClassView) OnIfaceStateChanged(name string, ifIndex int, state ifacemonitor.State) { + cv.routeTable.OnIfaceStateChanged(name, ifIndex, state) +} + +func (cv *ClassView) QueueResync() { + cv.routeTable.QueueResync() +} + +func (cv *ClassView) Apply() error { + return cv.routeTable.Apply() +} + +func (cv *ClassView) SetRoutes(ifaceName string, targets []Target) { + cv.routeTable.SetRoutes(cv.class, ifaceName, targets) +} + +func (cv *ClassView) RouteRemove(ifaceName string, cidr ip.CIDR) { + cv.routeTable.RouteRemove(cv.class, ifaceName, cidr) +} + +func (cv *ClassView) RouteUpdate(ifaceName string, target Target) { + cv.routeTable.RouteUpdate(cv.class, ifaceName, target) +} + +func (cv *ClassView) Index() int { + return cv.routeTable.Index() +} + +func (cv *ClassView) QueueResyncIface(ifaceName string) { + cv.routeTable.QueueResyncIface(ifaceName) +} + +func (cv *ClassView) ReadRoutesFromKernel(ifaceName string) ([]Target, error) { + return cv.routeTable.ReadRoutesFromKernel(ifaceName) +} + +var _ SyncerInterface = (*ClassView)(nil) diff --git a/felix/routetable/ownershippol/iface_ownership_policy.go b/felix/routetable/ownershippol/iface_ownership_policy.go new file mode 100644 index 00000000000..a9312487612 --- /dev/null +++ b/felix/routetable/ownershippol/iface_ownership_policy.go @@ -0,0 +1,50 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ownershippol + +import ( + "github.com/vishvananda/netlink" +) + +type ExclusiveOwnershipPolicy struct { + InterfaceNames []string +} + +func (d *ExclusiveOwnershipPolicy) IfaceShouldHaveARPEntries(ifaceName string) bool { + // Returning true so that we defer to the RouteTable's main ARP + // configuration. + return true +} +func (d *ExclusiveOwnershipPolicy) IfaceShouldHaveGracePeriod(ifaceName string) bool { + // Returning true so that we defer to the RouteTable's main grace period + // configuration. + return true +} + +func (d *ExclusiveOwnershipPolicy) IfaceIsOurs(ifaceName string) bool { + if d.InterfaceNames == nil { + return true + } + for _, iface := range d.InterfaceNames { + if iface == ifaceName { + return true + } + } + return false +} + +func (d *ExclusiveOwnershipPolicy) RouteIsOurs(ifaceName string, route *netlink.Route) bool { + return true +} diff --git a/felix/routetable/ownershippol/main_route_table_policy.go b/felix/routetable/ownershippol/main_route_table_policy.go new file mode 100644 index 00000000000..4480ade8d03 --- /dev/null +++ b/felix/routetable/ownershippol/main_route_table_policy.go @@ -0,0 +1,173 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ownershippol + +import ( + "strings" + + "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" + + "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs" + "github.com/projectcalico/calico/felix/routetable" +) + +// NewMainTable calculates the ownership policy for the main routing +// table, given Felix's configuration. +func NewMainTable( + vxlanIfaceName string, + deviceRouteProto netlink.RouteProtocol, + workloadIfacePrefixes []string, + removeExternalRoutes bool, +) *MainTableOwnershipPolicy { + var allRouteProtos []netlink.RouteProtocol + var exclusiveRouteProtos []netlink.RouteProtocol + if deviceRouteProto == unix.RTPROT_BOOT { + // RTPROTO_BOOT ended up being our default a long time ago, but it was + // a bad choice. Originally, it didn't matter because we didn't use + // the protocol to distinguish our routes (we used the interface name + // instead). However, when we added VXLAN, we needed to add blackhole + // and same-subnet routes, which don't relate to a Calico-owned + // interface. To avoid churning routes, we ended up using a new proto + // value just for the routes we needed to distinguish. + // + // So, if we see RTPROTO_BOOT on a route, it's ours if it's also + // associated with one of our interfaces. But, if we see a route with + // defaultVXLANProto, we know it's ours. + allRouteProtos = []netlink.RouteProtocol{unix.RTPROT_BOOT, dataplanedefs.VXLANDefaultProto} + exclusiveRouteProtos = []netlink.RouteProtocol{dataplanedefs.VXLANDefaultProto} + } else { + // If DeviceRouteProtocol is not RTPROTO_BOOT, then we use that value + // for all our routes and we don't need to worry about RTPROTO_BOOT. + allRouteProtos = []netlink.RouteProtocol{deviceRouteProto} + exclusiveRouteProtos = []netlink.RouteProtocol{deviceRouteProto} + } + ownershipPolicy := &MainTableOwnershipPolicy{ + WorkloadInterfacePrefixes: workloadIfacePrefixes, + RemoveNonCalicoWorkloadRoutes: removeExternalRoutes, + CalicoSpecialInterfaces: []string{ + // Always including VXLAN device, even if not enabled. That means + // we'll clean up the routes if VXLAN is disabled. + vxlanIfaceName, + dataplanedefs.BPFInDev, + // Not including routetable.InterfaceNone because MainTableOwnershipPolicy + // automatically handles it. + // Not including tunl0, it is managed by BIRD. + // Not including Wireguard, it has its own routing table. + }, + AllRouteProtocols: allRouteProtos, + ExclusiveRouteProtocols: exclusiveRouteProtos, + } + return ownershipPolicy +} + +// MainTableOwnershipPolicy is the MainTableOwnershipPolicy for the main routing table. +// It needs to discriminate between our routes and routes from other +// applications. It does that based on various heuristics that try to +// capture Felix's current and historic behaviour. It would have been a +// lot cleaner if we'd picked a "protocol" value for all our routes on day one +// and stuck to it! +type MainTableOwnershipPolicy struct { + WorkloadInterfacePrefixes []string + RemoveNonCalicoWorkloadRoutes bool + + // CalicoSpecialInterfaces is a list of interfaces that Calico uses for + // tunnels and special purposes. + CalicoSpecialInterfaces []string + + // AllRouteProtocols is a list of protocols that Calico uses, + // but may be used by other software too. + AllRouteProtocols []netlink.RouteProtocol + + // ExclusiveRouteProtocols is a list of protocols that should only be + // used by Calico. + ExclusiveRouteProtocols []netlink.RouteProtocol +} + +func (d *MainTableOwnershipPolicy) IfaceShouldHaveARPEntries(ifaceName string) bool { + return d.isWorkloadInterface(ifaceName) +} + +func (d *MainTableOwnershipPolicy) IfaceShouldHaveGracePeriod(ifaceName string) bool { + return d.isWorkloadInterface(ifaceName) +} + +func (d *MainTableOwnershipPolicy) isWorkloadInterface(ifaceName string) bool { + for _, prefix := range d.WorkloadInterfacePrefixes { + if strings.HasPrefix(ifaceName, prefix) { + return true + } + } + return false +} + +func (d *MainTableOwnershipPolicy) IfaceIsOurs(_ string) bool { + // In the main routing table, we need to keep track of all interfaces + // so that we can handle cases such as "same-subnet" VXLAN routes moving + // between interfaces when the parent device changes. + return true +} + +func (d *MainTableOwnershipPolicy) RouteIsOurs(ifaceName string, route *netlink.Route) bool { + // Check for routes that have a unique protocol that only Calico should + // be using. We can safely assume that these belong to us. + // + // This covers: + // - VXLAN "same-subnet" routes via the host's main NIC. + // - Special no-interface routes such as blackhole/prohibit. + for _, protocol := range d.ExclusiveRouteProtocols { + if route.Protocol == protocol { + return true + } + } + + // "No-interface" special routes can only be ours if they have one + // of our exclusive proto values, so, if we got no hit above, we + // can assume it's not ours. + if ifaceName == routetable.InterfaceNone { + return false + } + + if d.isWorkloadInterface(ifaceName) { + if d.RemoveNonCalicoWorkloadRoutes { + // We're configured to assume that any route to one of our + // interfaces is ours, no need to check the protocol. + return true + } + // Otherwise, we need to check the route's protocol. We use the + // more permissive protocol value here because we already know that + // this is one of our interfaces so the route is very likely to be + // ours. + for _, protocol := range d.AllRouteProtocols { + if route.Protocol == protocol { + return true + } + } + // Calico interface but not our route. + return false + } + + // Check if this route goes to one of our tunnel/special purpose + // interfaces. These are always ours. + for _, iface := range d.CalicoSpecialInterfaces { + if ifaceName == iface { + return true + } + } + + return false +} + +var _ routetable.OwnershipPolicy = (*MainTableOwnershipPolicy)(nil) diff --git a/felix/routetable/route_table.go b/felix/routetable/route_table.go index 4845c36955a..6884f2bd6a1 100644 --- a/felix/routetable/route_table.go +++ b/felix/routetable/route_table.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows + package routetable import ( @@ -19,7 +21,6 @@ import ( "fmt" "net" "reflect" - "regexp" "strings" "syscall" "time" @@ -30,6 +31,7 @@ import ( "golang.org/x/sys/unix" "github.com/projectcalico/calico/felix/conntrack" + "github.com/projectcalico/calico/felix/deltatracker" "github.com/projectcalico/calico/felix/environment" "github.com/projectcalico/calico/felix/ifacemonitor" "github.com/projectcalico/calico/felix/ip" @@ -41,244 +43,234 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/set" ) -var ( - GetFailed = errors.New("netlink get operation failed") - ConnectFailed = errors.New("connect to netlink failed") - ListFailed = errors.New("netlink list operation failed") - UpdateFailed = errors.New("netlink update operation failed") - IfaceNotPresent = errors.New("interface not present") - IfaceDown = errors.New("interface down") - IfaceGrace = errors.New("interface in cleanup grace period") +const ( + routeListFilterAttempts = 5 +) +var ( ipV6LinkLocalCIDR = ip.MustParseCIDROrIP("fe80::/64") - listIfaceTime = cprometheus.NewSummary(prometheus.SummaryOpts{ - Name: "felix_route_table_list_seconds", - Help: "Time taken to list all the interfaces during a resync.", + resyncTimeSummary = cprometheus.NewSummary(prometheus.SummaryOpts{ + Name: "felix_route_table_resync_seconds", + Help: "Time taken to list all the routes during a resync.", + }) + partialResyncTimeSummary = cprometheus.NewSummary(prometheus.SummaryOpts{ + Name: "felix_route_table_partial_resync_seconds", + Help: "Time taken to resync the routes of a single interface.", }) - perIfaceSyncTime = cprometheus.NewSummary(prometheus.SummaryOpts{ - Name: "felix_route_table_per_iface_sync_seconds", - Help: "Time taken to sync each interface", + conntrackBlockTimeSummary = cprometheus.NewSummary(prometheus.SummaryOpts{ + Name: "felix_route_table_conntrack_wait_seconds", + Help: "Time waiting for conntrack cleanups to finish.", }) + gaugeVecNumRoutes = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "felix_route_table_num_routes", + Help: "Number of routes that Felix is managing in the particular routing table.", + }, []string{"table"}) + gaugeVecNumIfaces = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "felix_route_table_num_ifaces", + Help: "Number of interfaces that Felix is monitoring for the particular routing table.", + }, []string{"table"}) + + defaultCIDRv4, _ = ip.ParseCIDROrIP("0.0.0.0/0") + defaultCIDRv6, _ = ip.ParseCIDROrIP("::/0") ) func init() { - prometheus.MustRegister(listIfaceTime, perIfaceSyncTime) -} - -const ( - // Use this for targets with no outbound interface. - InterfaceNone = "*NoOIF*" -) - -type TargetType string - -const ( - TargetTypeLocal TargetType = "local" - TargetTypeVXLAN TargetType = "vxlan" - TargetTypeNoEncap TargetType = "noencap" - TargetTypeOnLink TargetType = "onlink" - TargetTypeGlobalUnicast TargetType = "global-unicast" - TargetTypeLinkLocalUnicast TargetType = "local-unicast" - - // The following target types should be used with InterfaceNone. - TargetTypeBlackhole TargetType = "blackhole" - TargetTypeProhibit TargetType = "prohibit" - TargetTypeThrow TargetType = "throw" - TargetTypeUnreachable TargetType = "unreachable" -) - -const ( - maxApplyRetries = 2 -) - -type Target struct { - Type TargetType - CIDR ip.CIDR - GW ip.Addr - Src ip.Addr - DestMAC net.HardwareAddr -} - -func (t Target) Equal(t2 Target) bool { - return reflect.DeepEqual(t, t2) -} - -func (t Target) RouteType() int { - switch t.Type { - case TargetTypeLocal: - return syscall.RTN_LOCAL - case TargetTypeThrow: - return syscall.RTN_THROW - case TargetTypeBlackhole: - return syscall.RTN_BLACKHOLE - case TargetTypeProhibit: - return syscall.RTN_PROHIBIT - case TargetTypeUnreachable: - return syscall.RTN_UNREACHABLE - default: - return syscall.RTN_UNICAST - } -} - -func (t Target) RouteScope() netlink.Scope { - switch t.Type { - case TargetTypeLocal: - return netlink.SCOPE_HOST - case TargetTypeLinkLocalUnicast: - return netlink.SCOPE_LINK - case TargetTypeGlobalUnicast: - return netlink.SCOPE_UNIVERSE - case TargetTypeNoEncap: - return netlink.SCOPE_UNIVERSE - case TargetTypeVXLAN: - return netlink.SCOPE_UNIVERSE - case TargetTypeThrow: - return netlink.SCOPE_UNIVERSE - case TargetTypeBlackhole: - return netlink.SCOPE_UNIVERSE - case TargetTypeProhibit: - return netlink.SCOPE_UNIVERSE - case TargetTypeOnLink: - return netlink.SCOPE_LINK - default: - return netlink.SCOPE_LINK - } -} - -func (t Target) Flags() netlink.NextHopFlag { - switch t.Type { - case TargetTypeVXLAN, TargetTypeNoEncap, TargetTypeOnLink: - return syscall.RTNH_F_ONLINK - default: - return 0 - } + prometheus.MustRegister( + resyncTimeSummary, + partialResyncTimeSummary, + conntrackBlockTimeSummary, + gaugeVecNumRoutes, + gaugeVecNumIfaces, + ) } -type updateType byte - -const ( - updateTypeFullResync updateType = iota - updateTypeDelta -) - -// RouteTable manages calico routes for a specific table. It reconciles the -// routes that we desire to have for calico managed devices with what is the -// current status in the dataplane. That is, it removes any routes that we do -// not desire and adds those that we do. It skips over devices that we do not -// manage not to interfere with other users of the route tables. +// RouteTable manages the Calico routes for a specific kernel routing table. +// +// There are several complicating factors to managing the routes and all of +// these have caused real problems in the past: +// +// - There is more than one Felix subcomponent that needs to program routes, +// often into the same table. It is possible for different components to +// try to program conflicting routes for the same CIDR (for example, if a +// local and remote endpoint share the same IP address). To deal with this +// we assign a RouteClass to each potential source of routes and break +// ties on that value. +// +// - Most Calico components only deal with CIDRs and interfaces, but the +// kernel routing table is indexed by CIDR, metric and ToS field. To handle +// this difference in indexing, we use a DeltaTracker indexed in a way that +// matches the kernel's indexing. That allows us to correctly clean up any +// kernel routes that would alias if we only considered CIDR. +// +// - We need to translate interface name to interface index and that mapping +// can change over time. Interfaces can be renamed, keeping the same index. +// Interfaces can be recreated, keeping the same name but getting a new index. +// We handle this by indexing the routes we've been told to create on interface +// name and by listening for interface state changes. When an interface +// is updated, we re-calculate the routes that we want to program for it and +// re-do conflict resolution. +// +// - We can race with the interface monitor goroutine, being asked to program +// a route before we've heard about the interface, or spotting a new +// interface index when we do a read back of routes from the kernel. +// +// - The CNI plugin also programs the same routes that we do, so we can race +// with it as well. We may see an interface pop up with a route before we +// hear about the corresponding WorkloadEndpoint. To deal with that, we +// implement a grace period before deleting routes that belong to us but +// that we don't know about yet. +// +// - When IP addresses move from one interface to another (for example because +// a workload has been terminated and a new workload now has the IP) we need +// to clean up the conntrack entries from the old workload. We delegate this +// cleanup to the RouteOwnershipTracker; giving it callbacks when routes move. +// We do that cleanup in the background to avoid holding up other route +// programming. type RouteTable struct { logCxt *log.Entry ipVersion uint8 netlinkFamily int + // The routing table index. This is defaulted to RT_TABLE_MAIN if not specified. + tableIndex int - // Interface update tracking. - reSync bool - ifaceNameToUpdateType map[string]updateType - ifacePrefixRegexp *regexp.Regexp - includeNoInterface bool - - ifaceNameToTargets map[string]map[ip.CIDR]Target - ifaceNameToFirstSeen map[string]time.Time - pendingIfaceNameToDeltaTargets map[string]map[ip.CIDR]*Target - - pendingConntrackCleanups map[ip.Addr]chan struct{} - - deviceRouteSourceAddress net.IP + deviceRouteSourceAddress ip.Addr + defaultRouteProtocol netlink.RouteProtocol + removeExternalRoutes bool + ownershipPolicy OwnershipPolicy - deviceRouteProtocol netlink.RouteProtocol - removeExternalRoutes bool + // Interface update tracking. + fullResyncNeeded bool + ifacesToRescan set.Set[string] + makeARPEntries bool + haveMultiPathRoutes bool + + // ifaceToRoutes and cidrToIfaces are our inputs, updated + // eagerly when something in the manager layer tells us to change the + // routes. + ifaceToRoutes map[RouteClass]map[string]map[ip.CIDR]Target + cidrToIfaces map[RouteClass]map[ip.CIDR]set.Set[string] + + // kernelRoutes tracks the relationship between the route that we want + // to program for a given CIDR (i.e. the route selected after conflict + // resolution if there are multiple routes) and the route that's actually + // in the kernel. + kernelRoutes *deltatracker.DeltaTracker[kernelRouteKey, kernelRoute] + pendingARPs map[string]map[ip.Addr]net.HardwareAddr + + ifaceNameToIndex map[string]int + ifaceIndexToName map[int]string + ifaceIndexToState map[int]ifacemonitor.State + ifaceIndexToGraceInfo map[int]graceInfo + + conntrackCleanupEnabled bool + // conntrackTracker is a ConntrackCleanupManager or a NoOpRouteTracker + // Depending on whether conntrack cleanup is enabled or not. + conntrackTracker RouteOwnershipTracker nl *handlemgr.HandleManager - // The route table index. A value of 0 defaults to the main table. - tableIndex int - - // Testing shims, swapped with mock versions for UT - addStaticARPEntry func(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) error - conntrack conntrackIface - time timeshim.Interface - opReporter logutils.OpRecorder livenessCallback func() // The route deletion grace period. routeCleanupGracePeriod time.Duration + lastGracePeriodCleanup time.Time featureDetector environment.FeatureDetectorIface + + conntrack conntrackIface + time timeshim.Interface + newNetlinkHandle func() (netlinkshim.Interface, error) + + gaugeNumRoutes prometheus.Gauge + gaugeNumIfaces prometheus.Gauge +} + +type graceInfo struct { + FirstSeen time.Time + GraceExpired bool } -type RouteTableOpt func(table *RouteTable) +type Opt func(table *RouteTable) -func WithLivenessCB(cb func()) RouteTableOpt { +func WithLivenessCB(cb func()) Opt { return func(table *RouteTable) { table.livenessCallback = cb } } -func WithRouteCleanupGracePeriod(routeCleanupGracePeriod time.Duration) RouteTableOpt { +func WithRouteCleanupGracePeriod(routeCleanupGracePeriod time.Duration) Opt { return func(table *RouteTable) { table.routeCleanupGracePeriod = routeCleanupGracePeriod } } -func New( - interfaceRegexes []string, - ipVersion uint8, - netlinkTimeout time.Duration, - deviceRouteSourceAddress net.IP, - deviceRouteProtocol netlink.RouteProtocol, - removeExternalRoutes bool, - tableIndex int, - opReporter logutils.OpRecorder, - featureDetector environment.FeatureDetectorIface, - opts ...RouteTableOpt, -) *RouteTable { - return NewWithShims( - interfaceRegexes, - ipVersion, - netlinkshim.NewRealNetlink, - netlinkTimeout, - addStaticARPEntry, - conntrack.New(), - timeshim.RealTime(), - deviceRouteSourceAddress, - deviceRouteProtocol, - removeExternalRoutes, - tableIndex, - opReporter, - featureDetector, - opts..., - ) +func WithStaticARPEntries(b bool) Opt { + return func(table *RouteTable) { + if table.ipVersion != 4 { + log.Panic("Bug: ARP entries only supported for IPv4.") + } + table.makeARPEntries = b + } +} + +func WithConntrackCleanup(enabled bool) Opt { + return func(table *RouteTable) { + table.conntrackCleanupEnabled = enabled + } +} + +func WithTimeShim(shim timeshim.Interface) Opt { + return func(table *RouteTable) { + table.time = shim + } +} + +func WithConntrackShim(shim conntrackIface) Opt { + return func(table *RouteTable) { + table.conntrack = shim + } } -// NewWithShims is a test constructor, which allows netlink, arp and time to be replaced by shims. -func NewWithShims( - interfaceRegexes []string, +func WithNetlinkHandleShim(newNetlinkHandle func() (netlinkshim.Interface, error)) Opt { + return func(table *RouteTable) { + table.newNetlinkHandle = newNetlinkHandle + } +} + +// OwnershipPolicy is used to determine whether a given interface or route +// belongs to Calico. Routes that are loaded from the kernel are checked +// against this policy to determine if they should be tracked. The RouteTable +// cleans up tracked routes that don't match the current datastore state. +// +// The policy is also used to determine whether an interface should be tracked +// or not. If an interface is not tracked then the RouteTable will not be +// able to program routes for it, and it will not respond to interface state +// updates. This is mainly a performance optimisation for our non-main +// routing tables which tend to be used to manage routes for a single device. +type OwnershipPolicy interface { + RouteIsOurs(ifaceName string, route *netlink.Route) bool + + IfaceIsOurs(ifaceName string) bool + IfaceShouldHaveARPEntries(ifaceName string) bool + IfaceShouldHaveGracePeriod(ifaceName string) bool +} + +func New( + ownershipPolicy OwnershipPolicy, ipVersion uint8, - newNetlinkHandle func() (netlinkshim.Interface, error), netlinkTimeout time.Duration, - addStaticARPEntry func(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) error, - conntrack conntrackIface, - timeShim timeshim.Interface, deviceRouteSourceAddress net.IP, - deviceRouteProtocol netlink.RouteProtocol, + defaultRouteProtocol netlink.RouteProtocol, removeExternalRoutes bool, tableIndex int, opReporter logutils.OpRecorder, featureDetector environment.FeatureDetectorIface, - opts ...RouteTableOpt, + opts ...Opt, ) *RouteTable { - var filteredRegexes []string - includeNoOIF := false - - for _, interfaceRegex := range interfaceRegexes { - if interfaceRegex == InterfaceNone { - includeNoOIF = true - } else { - filteredRegexes = append(filteredRegexes, interfaceRegex) - } + if ownershipPolicy == nil { + log.Panic("Must provide an ownership policy.") } - if tableIndex == 0 { // If we set route.Table to 0, what we actually get is a route in RT_TABLE_MAIN. However, // RouteListFiltered is much more efficient if we give it the "real" table number. @@ -286,748 +278,1329 @@ func NewWithShims( tableIndex = unix.RT_TABLE_MAIN } - logCxt := log.WithFields(log.Fields{ - "ipVersion": ipVersion, - "tableIndex": tableIndex, + var logCxt *log.Entry + description := fmt.Sprintf("IPv%d:%d", ipVersion, tableIndex) + logCxt = log.WithFields(log.Fields{ + "table": description, }) - // Create a regexp matching the interfaces this route table manages. - var ifacePrefixRegexp *regexp.Regexp - if len(filteredRegexes) == 0 && len(interfaceRegexes) > 0 { - // All of the regexp parts were special matches for non-interface types. In this case don't match any - // interfaces. - logCxt.Info("No interface matches required for routetable") - } else { - // Either there were no regexp parts supplied (same as match all), or at least one real interface was included. - // Compile the interface regex. - ifaceNamePattern := strings.Join(filteredRegexes, "|") - logCxt = logCxt.WithField("ifaceRegex", ifaceNamePattern) - ifacePrefixRegexp = regexp.MustCompile(ifaceNamePattern) - logCxt.Info("Calculated interface name regexp") - } - family := netlink.FAMILY_V4 if ipVersion == 6 { family = netlink.FAMILY_V6 } else if ipVersion != 4 { - log.WithField("ipVersion", ipVersion).Panic("Unknown IP version") + logCxt.WithField("ipVersion", ipVersion).Panic("Unknown IP version") } rt := &RouteTable{ - logCxt: logCxt, - ipVersion: ipVersion, - netlinkFamily: family, - ifacePrefixRegexp: ifacePrefixRegexp, - includeNoInterface: includeNoOIF, - ifaceNameToTargets: map[string]map[ip.CIDR]Target{}, - ifaceNameToFirstSeen: map[string]time.Time{}, - pendingIfaceNameToDeltaTargets: map[string]map[ip.CIDR]*Target{}, - reSync: true, - ifaceNameToUpdateType: map[string]updateType{}, - pendingConntrackCleanups: map[ip.Addr]chan struct{}{}, - addStaticARPEntry: addStaticARPEntry, - conntrack: conntrack, - time: timeShim, - deviceRouteSourceAddress: deviceRouteSourceAddress, - deviceRouteProtocol: deviceRouteProtocol, - removeExternalRoutes: removeExternalRoutes, - tableIndex: tableIndex, - opReporter: opReporter, - livenessCallback: func() {}, - nl: handlemgr.NewHandleManager( - featureDetector, - handlemgr.WithNewHandleOverride(newNetlinkHandle), - handlemgr.WithSocketTimeout(netlinkTimeout), + logCxt: logCxt, + ipVersion: ipVersion, + netlinkFamily: family, + tableIndex: tableIndex, + + deviceRouteSourceAddress: ip.FromNetIP(deviceRouteSourceAddress), + defaultRouteProtocol: defaultRouteProtocol, + removeExternalRoutes: removeExternalRoutes, + + fullResyncNeeded: true, + ifacesToRescan: set.New[string](), + ownershipPolicy: ownershipPolicy, + + ifaceToRoutes: map[RouteClass]map[string]map[ip.CIDR]Target{}, + cidrToIfaces: map[RouteClass]map[ip.CIDR]set.Set[string]{}, + + kernelRoutes: deltatracker.New[kernelRouteKey, kernelRoute]( + deltatracker.WithValuesEqualFn[kernelRouteKey, kernelRoute](func(a, b kernelRoute) bool { + return a.Equals(b) + }), ), - featureDetector: featureDetector, + pendingARPs: map[string]map[ip.Addr]net.HardwareAddr{}, + + ifaceIndexToGraceInfo: map[int]graceInfo{}, + ifaceNameToIndex: map[string]int{}, + ifaceIndexToName: map[int]string{}, + ifaceIndexToState: map[int]ifacemonitor.State{}, + + conntrackCleanupEnabled: true, + + opReporter: opReporter, + livenessCallback: func() {}, + featureDetector: featureDetector, + + // Shims; may get overridden by options below. + conntrack: conntrack.New(), + time: timeshim.RealTime(), + newNetlinkHandle: netlinkshim.NewRealNetlink, + + gaugeNumRoutes: gaugeVecNumRoutes.WithLabelValues(description), + gaugeNumIfaces: gaugeVecNumIfaces.WithLabelValues(description), } for _, o := range opts { o(rt) } + rt.nl = handlemgr.NewHandleManager( + rt.featureDetector, + handlemgr.WithNewHandleOverride(rt.newNetlinkHandle), + handlemgr.WithSocketTimeout(netlinkTimeout), + ) + + if rt.conntrackCleanupEnabled { + rt.conntrackTracker = NewConntrackCleanupManager(ipVersion, rt.conntrack) + } else { + rt.conntrackTracker = NewNoOpRouteTracker() + } + return rt } -func (r *RouteTable) OnIfaceStateChanged(ifaceName string, state ifacemonitor.State) { +func (r *RouteTable) Index() int { + return r.tableIndex +} + +func (r *RouteTable) OnIfaceStateChanged(ifaceName string, ifIndex int, state ifacemonitor.State) { logCxt := r.logCxt.WithField("ifaceName", ifaceName) - if r.ifacePrefixRegexp == nil || !r.ifacePrefixRegexp.MatchString(ifaceName) { - logCxt.Debug("Ignoring interface state change, not an interface managed by this routetable.") + if !r.ownershipPolicy.IfaceIsOurs(ifaceName) { + logCxt.Trace("Ignoring interface state change, not an interface managed by this routetable.") return } + + // There are a couple of interesting corner cases: + // + // * Interface gets renamed: same ifindex, new name. The interface + // monitor deals with that by sending us a deletion for the old + // name, then a creation for the new name. + // * Interface gets recreated: same name, new ifindex. Again we + // should see a deletion and then an add. + + logCxt.WithFields(log.Fields{ + "ifIndex": ifIndex, + "state": state, + "name": ifaceName, + }).Debug("Interface state update.") + if state == ifacemonitor.StateNotPresent { + // Interface deleted, clean up. + oldIndex := r.ifaceNameToIndex[ifaceName] + delete(r.ifaceIndexToName, oldIndex) + delete(r.ifaceIndexToState, oldIndex) + delete(r.ifaceNameToIndex, ifaceName) + r.ifacesToRescan.Discard(ifaceName) + } else { + // Interface exists, record its details. + r.onIfaceSeen(ifIndex) + r.ifaceIndexToState[ifIndex] = state + oldIfIndex, ok := r.ifaceNameToIndex[ifaceName] + if ok && oldIfIndex != ifIndex { + // Interface renumbered. For example, deleted and then recreated + // with same name. Clean up old number. + delete(r.ifaceIndexToName, oldIfIndex) + } + r.ifaceNameToIndex[ifaceName] = ifIndex + r.ifaceIndexToName[ifIndex] = ifaceName + } + if state == ifacemonitor.StateUp { + // Interface transitioned to "up". Force a rescan of its routes + // because routes often get removed when the interface goes down + // and its default route disappears. logCxt.Debug("Interface up, marking for route sync") - r.ifaceNameToUpdateType[ifaceName] = updateTypeFullResync - r.onIfaceSeen(ifaceName) + r.ifacesToRescan.Add(ifaceName) + if r.haveMultiPathRoutes { + // The interface may be used by a next hop on a multi-path route. + // so we need to recheck everything. We only use multi-path + // for EGW tunnels right now so this will only be a handful of + // routes. + logCxt.Debug("Interface up, rechecking all multi-path routes.") + r.QueueResync() + } + } + + r.recheckRouteOwnershipsByIface(ifaceName) + + if r.haveMultiPathRoutes { + // Re-check all potential multi-path routes. We only use multi-path + // for EGW tunnels right now so this will only be a handful of routes. + logCxt.Debug("Rechecking all multi-path routes.") + r.recheckRouteOwnershipsByIface(InterfaceNone) } } -func (r *RouteTable) onIfaceSeen(ifaceName string) { - if _, ok := r.ifaceNameToFirstSeen[ifaceName]; ok { +func (r *RouteTable) onIfaceSeen(ifIndex int) { + if ifIndex <= 1 { + // Ignore "no interface" routes. return } - r.ifaceNameToFirstSeen[ifaceName] = r.time.Now() + if _, ok := r.ifaceIndexToGraceInfo[ifIndex]; ok { + return + } + r.ifaceIndexToGraceInfo[ifIndex] = graceInfo{ + FirstSeen: r.time.Now(), + } } -// markIfaceForUpdate marks an interface update is required. This is either a delta update from a route -// set, update, or remove, or a full resync triggered from start-up processing, QueueResync or a previous failed update. -func (r *RouteTable) markIfaceForUpdate(ifaceName string, resync bool) { - if resync { - // This is a full resync so flag as such. - r.ifaceNameToUpdateType[ifaceName] = updateTypeFullResync - } else if _, ok := r.ifaceNameToUpdateType[ifaceName]; !ok { - // This is not a full resync - set the update status if not already set (because we don't want to "downgrade" - // a full-resync to a delta update). - r.ifaceNameToUpdateType[ifaceName] = updateTypeDelta - } +func (r *RouteTable) QueueResyncIface(ifaceName string) { + r.ifacesToRescan.Add(ifaceName) } -// SetRoutes sets the full set of targets for the specified interface. This recalculates the deltas from the current -// set of programmed routes. -func (r *RouteTable) SetRoutes(ifaceName string, targets []Target) { - if ifaceName == InterfaceNone && !r.includeNoInterface { - r.logCxt.Error("Setting route with no interface") +// SetRoutes replaces the full set of targets for the specified interface. +func (r *RouteTable) SetRoutes(routeClass RouteClass, ifaceName string, targets []Target) { + if !r.ownershipPolicy.IfaceIsOurs(ifaceName) { + r.logCxt.WithField("ifaceName", ifaceName).Error( + "Cannot set route for interface not managed by this routetable.") return } + r.logCxt.WithFields(log.Fields{ + "routeClass": routeClass, + "ifaceName": ifaceName, + "targets": targets, + }).Debug("SetRoutes called.") + r.checkTargets(ifaceName, targets...) - currentCIDRsToTarget := r.ifaceNameToTargets[ifaceName] - deltas := map[ip.CIDR]*Target{} + if r.ifaceToRoutes[routeClass] == nil { + r.ifaceToRoutes[routeClass] = map[string]map[ip.CIDR]Target{} + } - // Delete all of the existing targets. - for cidr := range currentCIDRsToTarget { - deltas[cidr] = nil + // Figure out what has changed. + oldTargetsToCleanUp := r.ifaceToRoutes[routeClass][ifaceName] + newTargets := map[ip.CIDR]Target{} + for _, t := range targets { + delete(oldTargetsToCleanUp, t.CIDR) + newTargets[t.CIDR] = t } - // Add the new targets. - for _, target := range targets { - if current, ok := currentCIDRsToTarget[target.CIDR]; ok && current.Equal(target) { - // Entry is unchanged. Remove from the deltas. - log.Debugf("Expected target unchanged for CIDR: %v", target.CIDR) - delete(deltas, target.CIDR) - } else { - // Entry has either been modified or been created. If modified then we'll keep the delete followed by a - // create. - log.Debugf("New target for CIDR: %v", target.CIDR) - deltas[target.CIDR] = safeTargetPointer(target) - } + // Record the new desired state. + if len(newTargets) == 0 { + r.logCxt.Debug("No routes for this interface, removing from map.") + delete(r.ifaceToRoutes[routeClass], ifaceName) + } else { + r.ifaceToRoutes[routeClass][ifaceName] = newTargets } - // Store the routes. Remove any delta routes since this is a full set of routes. - r.pendingIfaceNameToDeltaTargets[ifaceName] = deltas - r.markIfaceForUpdate(ifaceName, false) + // Clean up the old CIDRs. + for cidr := range oldTargetsToCleanUp { + r.logCxt.WithField("cidr", cidr).Debug("Cleaning up old route.") + // removeOwningIface() calls recalculateDesiredKernelRoute. + r.removeOwningIface(routeClass, ifaceName, cidr) + } + + // Clean out the pending ARP list, then recalculate it below. + delete(r.pendingARPs, ifaceName) + for cidr, target := range newTargets { + // addOwningIface() calls recalculateDesiredKernelRoute. + r.addOwningIface(routeClass, ifaceName, cidr) + r.updatePendingARP(ifaceName, cidr.Addr(), target.DestMAC) + } } -// RouteUpdate updates the route keyed off the target CIDR. These deltas will be applied to any routes set using -// SetRoute. -func (r *RouteTable) RouteUpdate(ifaceName string, target Target) { - if ifaceName == InterfaceNone && !r.includeNoInterface { - r.logCxt.Error("Updating route with no interface") +// RouteUpdate updates the route keyed off the target CIDR. These deltas will +// be applied to any routes set using SetRoute. +func (r *RouteTable) RouteUpdate(routeClass RouteClass, ifaceName string, target Target) { + if !r.ownershipPolicy.IfaceIsOurs(ifaceName) { + r.logCxt.WithField("ifaceName", ifaceName).Error( + "Cannot set route for interface not managed by this routetable.") return } + r.checkTargets(ifaceName, target) - if r.pendingIfaceNameToDeltaTargets[ifaceName] == nil { - r.pendingIfaceNameToDeltaTargets[ifaceName] = map[ip.CIDR]*Target{} + if r.ifaceToRoutes[routeClass] == nil { + r.ifaceToRoutes[routeClass] = map[string]map[ip.CIDR]Target{} } - if current, ok := r.ifaceNameToTargets[ifaceName][target.CIDR]; ok && current.Equal(target) { - // Target unchanged from current programmed route, remove deltas. - r.logCxt.Debugf("Target unchanged for CIDR %s", target.CIDR) - delete(r.pendingIfaceNameToDeltaTargets[ifaceName], target.CIDR) - } else { - // Target new or changed, save delta. - r.pendingIfaceNameToDeltaTargets[ifaceName][target.CIDR] = &target - r.markIfaceForUpdate(ifaceName, false) + + routesByCIDR := r.ifaceToRoutes[routeClass][ifaceName] + if routesByCIDR == nil { + routesByCIDR = map[ip.CIDR]Target{} + r.ifaceToRoutes[routeClass][ifaceName] = routesByCIDR } + routesByCIDR[target.CIDR] = target + r.addOwningIface(routeClass, ifaceName, target.CIDR) + r.updatePendingARP(ifaceName, target.CIDR.Addr(), target.DestMAC) } -// RouteRemove removes the route with the specified CIDR. These deltas will be applied to any routes set using -// SetRoute. -func (r *RouteTable) RouteRemove(ifaceName string, cidr ip.CIDR) { - if ifaceName == InterfaceNone && !r.includeNoInterface { - r.logCxt.Error("Removing route with no interface") +// RouteRemove removes the route with the specified CIDR. These deltas will +// be applied to any routes set using SetRoute. +func (r *RouteTable) RouteRemove(routeClass RouteClass, ifaceName string, cidr ip.CIDR) { + if !r.ownershipPolicy.IfaceIsOurs(ifaceName) { + r.logCxt.WithField("ifaceName", ifaceName).Error( + "Cannot set route for interface not managed by this routetable.") return } - if r.pendingIfaceNameToDeltaTargets[ifaceName] == nil { - r.pendingIfaceNameToDeltaTargets[ifaceName] = map[ip.CIDR]*Target{} + delete(r.ifaceToRoutes[routeClass][ifaceName], cidr) + if len(r.ifaceToRoutes[routeClass][ifaceName]) == 0 { + delete(r.ifaceToRoutes[routeClass], ifaceName) } - if _, ok := r.ifaceNameToTargets[ifaceName][cidr]; !ok { - // Target not programmed, remote deltas. - r.logCxt.Debugf("Target is not programmed for CIDR %s", cidr) - delete(r.pendingIfaceNameToDeltaTargets[ifaceName], cidr) - } else { - // Target programmed, set delta for deletion. - r.pendingIfaceNameToDeltaTargets[ifaceName][cidr] = nil - r.markIfaceForUpdate(ifaceName, false) + r.removeOwningIface(routeClass, ifaceName, cidr) + r.removePendingARP(ifaceName, cidr.Addr()) +} + +func (r *RouteTable) updatePendingARP(ifaceName string, addr ip.Addr, mac net.HardwareAddr) { + if !r.makeARPEntries { + return + } + if len(mac) == 0 { + r.removePendingARP(ifaceName, addr) + return + } + r.logCxt.Debug("Adding pending ARP entry.") + if r.pendingARPs[ifaceName] == nil { + r.pendingARPs[ifaceName] = map[ip.Addr]net.HardwareAddr{} } + r.pendingARPs[ifaceName][addr] = mac } -func (r *RouteTable) QueueResync() { - r.logCxt.Debug("Queueing a resync of routing table.") - r.reSync = true +func (r *RouteTable) removePendingARP(ifaceName string, addr ip.Addr) { + if !r.makeARPEntries { + return + } + if pending, ok := r.pendingARPs[ifaceName]; ok { + delete(pending, addr) + if len(pending) == 0 { + delete(r.pendingARPs, ifaceName) + } + } } -func (r *RouteTable) Apply() error { - if r.reSync { - r.opReporter.RecordOperation(fmt.Sprint("resync-routes-v", r.ipVersion)) +func (r *RouteTable) addOwningIface(class RouteClass, ifaceName string, cidr ip.CIDR) { + if r.cidrToIfaces[class] == nil { + r.cidrToIfaces[class] = map[ip.CIDR]set.Set[string]{} + } + ifaceNames := r.cidrToIfaces[class][cidr] + if ifaceNames == nil { + ifaceNames = set.New[string]() + r.cidrToIfaces[class][cidr] = ifaceNames + } + ifaceNames.Add(ifaceName) + r.recalculateDesiredKernelRoute(cidr) +} - listStartTime := time.Now() +func (r *RouteTable) removeOwningIface(class RouteClass, ifaceName string, cidr ip.CIDR) { + ifaceNames, ok := r.cidrToIfaces[class][cidr] + if !ok { + return + } + ifaceNames.Discard(ifaceName) + if ifaceNames.Len() == 0 { + delete(r.cidrToIfaces[class], cidr) + } + r.recalculateDesiredKernelRoute(cidr) +} - if r.ifacePrefixRegexp != nil { - // If there is an interface regex then we need to query links to find matching links for this route table - // instance and mark the interface for update. - log.Debug("Check interfaces matching regex") - nl, err := r.nl.Handle() - if err != nil { - r.logCxt.WithError(err).Error("Failed to connect to netlink, retrying...") - return ConnectFailed - } - links, err := nl.LinkList() - if err != nil { - r.logCxt.WithError(err).Error("Failed to list interfaces, retrying...") - r.nl.MarkHandleForReopen() // Defensive: force a netlink reconnection next time. - return ListFailed - } - // Track the seen interfaces, and for each seen interface flag for full resync. No point in doing a full resync - // for interfaces that are still in our cache and have been deleted, so leave them unchanged - if there are any - // route deletions then the delta processing for those interfaces will ensure conntrack entries are deleted. - seen := set.New[string]() - for _, link := range links { - r.livenessCallback() - attrs := link.Attrs() - if attrs == nil { - continue - } - ifaceName := attrs.Name - if r.ifacePrefixRegexp.MatchString(ifaceName) { - r.logCxt.WithField("ifaceName", ifaceName).Debug( - "Resync: found calico-owned interface") - r.markIfaceForUpdate(ifaceName, true) - r.onIfaceSeen(ifaceName) - seen.Add(ifaceName) - } - } - // Clean up first-seen timestamps for old interfaces. - // Resyncs happen periodically, so the amount of memory leaked to old - // first seen timestamps is small. - for name, firstSeen := range r.ifaceNameToFirstSeen { - if seen.Contains(name) { - // Interface still present. - continue - } - if r.time.Since(firstSeen) < r.routeCleanupGracePeriod { - // Interface first seen recently. - continue - } - log.WithField("ifaceName", name).Debug( - "Cleaning up timestamp for removed interface.") - delete(r.ifaceNameToFirstSeen, name) +// recheckRouteOwnershipsByIface reruns conflict resolution for all +// the interface's routes. +func (r *RouteTable) recheckRouteOwnershipsByIface(name string) { + seen := set.New[ip.CIDR]() + for _, ifaceToRoutes := range r.ifaceToRoutes { + for cidr := range ifaceToRoutes[name] { + if seen.Contains(cidr) { + continue } + r.recalculateDesiredKernelRoute(cidr) + seen.Add(cidr) } + } +} - // If we are managing no-OIF routes then add that to our dirty set. - if r.includeNoInterface { - log.Debug("Flag no OIF for full re-sync") - r.markIfaceForUpdate(InterfaceNone, true) +func (r *RouteTable) ifaceIndexForName(ifaceName string) (int, bool) { + if ifaceName == InterfaceNone { + if r.ipVersion == 6 { + // IPv6 "special" routes use ifindex 1 (vs 0 for IPv4). + return 1, true + } else { + // IPv4 uses 0. + return 0, true } + } + + idx, ok := r.ifaceNameToIndex[ifaceName] + return idx, ok +} - r.reSync = false - listIfaceTime.Observe(r.time.Since(listStartTime).Seconds()) +func (r *RouteTable) ifaceNameForIndex(ifindex int) (string, bool) { + if ifindex <= 1 { + return InterfaceNone, true } + name, ok := r.ifaceIndexToName[ifindex] + return name, ok +} - graceIfaces := 0 - for retry := 0; retry < maxApplyRetries; retry++ { - ifaceLoop: - for ifaceName, ia := range r.ifaceNameToUpdateType { - logCxt := r.logCxt.WithField("ifaceName", ifaceName) - r.livenessCallback() - firstTry := retry == 0 - lastTry := retry == maxApplyRetries-1 - fullResync := ia == updateTypeFullResync || lastTry - err := r.syncRoutesForLink(ifaceName, fullResync, firstTry) - - // Handle errors from syncing either L2 or L3 routes. - switch err { - case nil: - logCxt.Debug("Synchronised routes on interface") - delete(r.ifaceNameToUpdateType, ifaceName) - continue ifaceLoop - case IfaceNotPresent: - logCxt.Info("Interface missing, will retry if it appears.") - delete(r.ifaceNameToUpdateType, ifaceName) - continue ifaceLoop - case IfaceDown: - logCxt.Info("Interface down, will retry if it goes up.") - delete(r.ifaceNameToUpdateType, ifaceName) - continue ifaceLoop - case IfaceGrace: - if lastTry { - logCxt.Info("Interface in cleanup grace period, will retry after.") - } - graceIfaces++ - continue ifaceLoop - } +func (r *RouteTable) recalculateDesiredKernelRoute(cidr ip.CIDR) { + defer r.updateGauges() + kernKey := r.routeKeyForCIDR(cidr) + oldDesiredRoute, _ := r.kernelRoutes.Desired().Get(kernKey) - if lastTry { - // The interface might be flapping or being deleted. Flag that it will require a full re-sync - logCxt.Warn("Failed to sync routes to interface even after retries. " + - "Leaving it dirty, requiring a full sync.") - r.markIfaceForUpdate(ifaceName, true) - } + var bestTarget Target + bestRouteClass := RouteClassMax + bestIface := "" + bestIfaceIdx := -1 + var candidates []string + + for routeClass, cidrToIface := range r.cidrToIfaces { + ifaces := cidrToIface[cidr] + if ifaces == nil { + continue } - } - r.livenessCallback() - r.cleanUpPendingConntrackDeletions() - // Don't return a failure if there are only interfaces in the cleanup grace period. - // They'll be retried on the next invocation (the route refresh timer), and we mustn't - // count them as Sync Errors. - if len(r.ifaceNameToUpdateType) > graceIfaces { - r.logCxt.Warn("Some interfaces still out-of sync.") - return UpdateFailed - } + // In case of conflicts (more than one route with the same CIDR), pick + // one deterministically so that we don't churn the dataplane. - return nil -} + ifaces.Iter(func(ifaceName string) error { + candidates = append(candidates, ifaceName) + ifIndex, ok := r.ifaceIndexForName(ifaceName) + if !ok { + r.logCxt.WithField("ifaceName", ifaceName).Debug("Skipping route for missing interface.") + return nil + } -func (r *RouteTable) syncRoutesForLink(ifaceName string, fullSync bool, firstTry bool) error { - startTime := time.Now() - defer func() { - perIfaceSyncTime.Observe(r.time.Since(startTime).Seconds()) - }() - logCxt := r.logCxt.WithField("ifaceName", ifaceName) - logCxt.Debug("Syncing interface routes") + someUp := false + target, ok := r.ifaceToRoutes[routeClass][ifaceName][cidr] + if !ok { + log.WithFields(log.Fields{ + "ifaceName": ifaceName, + "cidr": cidr, + }).Warn("Bug? No route for iface/CIDR (recalculateDesiredKernelRoute called too early?).") + return nil + } + for _, nh := range target.MultiPath { + if ifIndex, ok := r.ifaceIndexForName(nh.IfaceName); !ok { + r.logCxt.WithField("ifaceName", nh.IfaceName).Debug("Skipping multi-path route for missing interface.") + return nil + } else { + if r.ifaceIndexToState[ifIndex] == ifacemonitor.StateUp { + someUp = true + } + } + } - // Any deleted route that is not being replaced by a route with the same CIDR should have the corresponding - // conntrack entry removed. - deletedConnCIDRs := set.New[ip.CIDR]() - defer func() { - cidrsToTarget := r.ifaceNameToTargets[ifaceName] - deletedConnCIDRs.Iter(func(cidr ip.CIDR) error { - if _, ok := cidrsToTarget[cidr]; !ok { - // Route is deleted and CIDR should not be routable anymore - remove conntrack entries. - r.startConntrackDeletion(cidr.Addr()) + // We've got some routes for this interface, force-expire its + // grace period. + if graceInf, ok := r.ifaceIndexToGraceInfo[ifIndex]; ok { + graceInf.GraceExpired = true + r.ifaceIndexToGraceInfo[ifIndex] = graceInf + } + + if ifaceName != InterfaceNone && r.ifaceIndexToState[ifIndex] != ifacemonitor.StateUp { + r.logCxt.WithField("ifaceName", ifaceName).Debug("Skipping route for down interface.") + return nil + } else if len(target.MultiPath) > 0 && !someUp { + // Multi-path routes require at least one interface to be up. + r.logCxt.Debug("Skipping multi-path route; all interfaces down.") + return nil + } + + // Main tie-breaker is the RouteClass, which is prioritised + // by the function of the routes. For example, local workload routes + // take precedence over VXLAN tunnel routes. + if routeClass < bestRouteClass || (routeClass == bestRouteClass && ifIndex > bestIfaceIdx) { + bestIface = ifaceName + bestIfaceIdx = ifIndex + bestRouteClass = routeClass + bestTarget = target } return nil }) - }() + } - // If necessary perform a full resync. This will return a set of routes that need deleting and will update the - // deltas to fix any discrepancies with the expected configuration. If this errors, we still apply the deltas - // first because this allows us to tidy up configuration for interfaces that no longer have any routes associated - // with them. - var routesToDelete []netlink.Route - updatesFailed := false - var resyncErr error - if fullSync { - // Performing a full re-sync. Start by applying the deltas so that we don't delete routes that are required. - logCxt.Debug("Reconcile against kernel programming") - _, _ = r.applyRouteDeltas(ifaceName, deletedConnCIDRs) - - // Now do the resync - this will update our deltas again based on what is not programmed (it's a little bit - // circuitous, but simplifies the code paths for resync and delta processing). - if routesToDelete, resyncErr = r.fullResyncRoutesForLink(logCxt, ifaceName, deletedConnCIDRs); resyncErr != nil && resyncErr != IfaceGrace { - // If we hit anything other than an interface-in-grace error, exit now. - r.logCxt.WithError(resyncErr).Info("Hit error doing kernel reconciliation") - return r.filterErrorByIfaceState(ifaceName, resyncErr, UpdateFailed, firstTry) + if bestIfaceIdx == -1 { + if len(candidates) == 0 { + r.logCxt.WithFields(log.Fields{ + "cidr": cidr, + }).Debug("CIDR no longer has any associated routes.") + } else { + r.logCxt.WithFields(log.Fields{ + "cidr": cidr, + "candidates": candidates, + }).Debug("No valid route for this CIDR (all candidate routes missing iface index).") } - // Ensure we have static ARP entries for all of our existing routes. - for _, target := range r.ifaceNameToTargets[ifaceName] { - if r.ipVersion == 4 && target.DestMAC != nil { - // TODO(smc) clean up/sync old ARP entries - r.livenessCallback() - err := r.addStaticARPEntry(target.CIDR, target.DestMAC, ifaceName) - if err != nil { - logCxt.WithError(err).Warn("Failed to set ARP entry") - updatesFailed = true - } + // Clean up the old entries. + r.kernelRoutes.Desired().Delete(kernKey) + r.conntrackTracker.RemoveCIDROwner(cidr) + return + } + + src := r.deviceRouteSourceAddress + if bestTarget.Src != nil { + src = bestTarget.Src + } + proto := r.defaultRouteProtocol + if bestTarget.Protocol != 0 { + proto = bestTarget.Protocol + } + kernRoute := kernelRoute{ + Type: bestTarget.RouteType(), + Scope: bestTarget.RouteScope(), + GW: bestTarget.GW, + Src: src, + Ifindex: bestIfaceIdx, + OnLink: bestTarget.Flags()&unix.RTNH_F_ONLINK != 0, + Protocol: proto, + } + if len(bestTarget.MultiPath) > 0 { + for _, nh := range bestTarget.MultiPath { + ifIndex, ok := r.ifaceIndexForName(nh.IfaceName) + if !ok { + log.Panic("Bug: multi-path route had missing interface after we already checked!") } + kernRoute.NextHops = append(kernRoute.NextHops, kernelNextHop{ + GW: nh.Gw, + Ifindex: ifIndex, + }) } - } + } else { + kernRoute.GW = bestTarget.GW + kernRoute.Ifindex = bestIfaceIdx + } + if log.IsLevelEnabled(log.DebugLevel) && !reflect.DeepEqual(oldDesiredRoute, kernRoute) { + r.logCxt.WithFields(log.Fields{ + "dst": kernKey, + "oldRoute": oldDesiredRoute, + "newRoute": kernRoute, + "iface": bestIface, + }).Debug("Preferred kernel route for this dest has changed.") + } else if log.IsLevelEnabled(log.DebugLevel) { + r.logCxt.WithFields(log.Fields{ + "dst": kernKey, + "route": kernRoute, + "iface": bestIface, + }).Debug("Preferred kernel route for this dest still the same.") + } + + r.kernelRoutes.Desired().Set(kernKey, kernRoute) + r.conntrackTracker.UpdateCIDROwner(cidr, bestIfaceIdx, bestRouteClass) +} - // Update the cached values from the deltas and get the set of targets to create and delete. - targetsToCreate, targetsToDelete := r.applyRouteDeltas(ifaceName, deletedConnCIDRs) +func (r *RouteTable) QueueResync() { + r.logCxt.Debug("Queueing a resync of routing table.") + r.fullResyncNeeded = true +} - // Try to get the link. This may fail if it's been deleted out from under us. - linkAttrs, err := r.getLinkAttributes(ifaceName) - if err != nil { - return err - } - nl, err := r.nl.Handle() +// ReadRoutesFromKernel offers partial support for reading back routes from the +// kernel. In particular, it assumes that "onlink" routes are VXLAN routes, +// which is lossy. Currently, this is only used in Enterprise, where the +// routes it needs to read are VXLAN routes. +func (r *RouteTable) ReadRoutesFromKernel(ifaceName string) ([]Target, error) { + r.logCxt.WithField("ifaceName", ifaceName).Debug("Reading routing table from kernel.") + r.ifacesToRescan.Add(ifaceName) + err := r.maybeResyncWithDataplane() if err != nil { - logCxt.Debug("Failed to connect to netlink") - return ConnectFailed + return nil, err } - // Add the target deletes to the set of routes to delete (we do this first so that we only have one set of deletion - // data that we use to tidy up routes and conntrack entries). - for _, target := range targetsToDelete { - routesToDelete = append(routesToDelete, r.createL3Route(linkAttrs, target)) + ifaceIndex, ok := r.ifaceIndexForName(ifaceName) + if !ok { + return nil, IfaceNotPresent } - // Delete the combined set of routes. - for _, route := range routesToDelete { - r.livenessCallback() - if err := nl.RouteDel(&route); err != nil { - logCxt.WithError(err).Warn("Failed to delete route") - updatesFailed = true + var allTargets []Target + r.kernelRoutes.Dataplane().Iter(func(key kernelRouteKey, kernRoute kernelRoute) { + if kernRoute.Ifindex != ifaceIndex { + return } - } - // Now add target routes. - for _, target := range targetsToCreate { - r.livenessCallback() - route := r.createL3Route(linkAttrs, target) - - // In case this IP is being re-used, wait for any previous conntrack entry - // to be cleaned up. (No-op if there are no pending deletes.) - r.waitForPendingConntrackDeletion(target.CIDR.Addr()) - - if firstTry || !r.shouldDeleteConflictingRoutes() { - // Even if we're in "delete conflicting" mode, we use RouteAdd on - // the first pass. This makes sure that we scan over all interfaces - // at least once before we start overwriting conflicting routes. - // This makes sure that we handle a common case where a route - // is being removed from one interface and added to another more - // cleanly. - err = nl.RouteAdd(&route) - } else { - err = nl.RouteReplace(&route) + target := Target{ + CIDR: key.CIDR, + Src: kernRoute.Src, + Protocol: kernRoute.Protocol, } - if err != nil { - if firstTry { - logCxt.WithError(err).WithField("route", route).Debug("Failed to add route on first attempt, retrying...") + + switch kernRoute.Type { + case unix.RTN_LOCAL: + target.Type = TargetTypeLocal + case unix.RTN_THROW: + target.Type = TargetTypeThrow + case unix.RTN_UNREACHABLE: + target.Type = TargetTypeUnreachable + case unix.RTN_BLACKHOLE: + target.Type = TargetTypeBlackhole + case unix.RTN_PROHIBIT: + target.Type = TargetTypeProhibit + case unix.RTN_UNICAST: + if kernRoute.Scope == unix.RT_SCOPE_LINK { + target.Type = TargetTypeLinkLocalUnicast } else { - logCxt.WithError(err).WithField("route", route).Warn("Failed to add route") + if kernRoute.OnLink { + // Ugh, this is a lossy reverse mapping. + // TODO align TargetTypes with kernel types! + target.Type = TargetTypeVXLAN + } else { + target.Type = TargetTypeGlobalUnicast + } } - updatesFailed = true - } else { - logCxt.WithField("route", route).Debug("Added route") } - if r.ipVersion == 4 && target.DestMAC != nil { - // TODO(smc) clean up/sync old ARP entries - err := r.addStaticARPEntry(target.CIDR, target.DestMAC, ifaceName) - if err != nil { - logCxt.WithError(err).Warn("Failed to set ARP entry") - updatesFailed = true + + if len(kernRoute.NextHops) > 0 { + // Multi-path route. + for _, nh := range kernRoute.NextHops { + ifaceName, ok := r.ifaceNameForIndex(nh.Ifindex) + if !ok { + r.logCxt.WithField("ifindex", nh.Ifindex).Warn("Next hop has unknown interface index.") + } + target.MultiPath = append(target.MultiPath, NextHop{ + Gw: nh.GW, + IfaceName: ifaceName, + }) } + } else { + // Single-path route. + target.GW = kernRoute.GW } - } - - if updatesFailed { - r.nl.MarkHandleForReopen() // Defensive: force a netlink reconnection next time. - - // Recheck whether the interface exists so we don't produce spammy logs during - // interface removal. - return r.filterErrorByIfaceState(ifaceName, UpdateFailed, UpdateFailed, firstTry) - } - // Return any un-handled re-sync error. - return resyncErr + allTargets = append(allTargets, target) + }) + return allTargets, nil } -func (r *RouteTable) applyRouteDeltas(ifaceName string, deletedConnCIDRs set.Set[ip.CIDR]) (targetsToCreate, targetsToDelete []Target) { - // Determine the set of deleted, created and current targets - cidrsToTarget := r.ifaceNameToTargets[ifaceName] - if cidrsToTarget == nil { - // Police against there being no existing targets, but handling a route update. - cidrsToTarget = map[ip.CIDR]Target{} - } - - // Now apply deltas to our cache and track targets to delete and create. - deltaTargets := r.pendingIfaceNameToDeltaTargets[ifaceName] - for cidr, target := range deltaTargets { - if current, ok := cidrsToTarget[cidr]; ok { - // Previous entry exists, so need to delete it. Note that the SetRoutes, RouteUpdate and RouteRemove will not - // add deltas for unchanged targets, so we don't need to check for target equivalency here. - log.Debugf("Deleted or updated CIDR: %v", cidr) - targetsToDelete = append(targetsToDelete, current) - deletedConnCIDRs.Add(cidr) - delete(cidrsToTarget, cidr) - } - if target != nil { - // Delta adds a new entry. - log.Debugf("Added or updated CIDR: %v", cidr) - targetsToCreate = append(targetsToCreate, *target) - cidrsToTarget[cidr] = *target +func (r *RouteTable) Apply() (err error) { + err = r.attemptApply(0) + if err != nil { + // To avoid log spam, only log if there was an unexpected problem. + r.logCxt.WithError(err).Warn("First attempt at updating routing table failed. Retrying...") + } + if err != nil || r.ifacesToRescan.Len() > 0 { + // Do one inline retry with a fresh netlink connection. + err = r.attemptApply(1) + if err != nil { + r.logCxt.WithError(err).Error("Second attempt at updating routing table failed. Will retry later.") + } else { + r.logCxt.WithError(err).Info("Retry was successful.") } } - - // Processed the deltas so remove them. - delete(r.pendingIfaceNameToDeltaTargets, ifaceName) - - // If there are no more expected targets for this interface then remove from the cache. - if len(cidrsToTarget) == 0 { - delete(r.ifaceNameToTargets, ifaceName) - } else { - r.ifaceNameToTargets[ifaceName] = cidrsToTarget + if r.ifacesToRescan.Len() > 0 { + // Make sure the dataplane reschedules us. + return fmt.Errorf("some interfaces flapped during route update: %s", r.ifacesToRescan.String()) } - - return + return err } -func (r *RouteTable) createL3Route(linkAttrs *netlink.LinkAttrs, target Target) netlink.Route { - log.Debugf("Create L3 route for: %#v", target) - var linkIndex int - if linkAttrs != nil { - linkIndex = linkAttrs.Index - } - cidr := target.CIDR - ipNet := cidr.ToIPNet() - route := netlink.Route{ - LinkIndex: linkIndex, - Dst: &ipNet, - Type: target.RouteType(), - Protocol: r.deviceRouteProtocol, - Scope: target.RouteScope(), - Table: r.tableIndex, +func (r *RouteTable) attemptApply(attempt int) (err error) { + defer func() { + if err != nil { + r.nl.MarkHandleForReopen() + } + }() + if err = r.maybeResyncWithDataplane(); err != nil { + return err + } + if err = r.applyUpdates(attempt); err != nil { + return err } + r.maybeCleanUpGracePeriods() + return nil +} - // If this is an IPv6 blackhole or throw route, set the dev to lo. This matches - // what the kernel does, and ensures we properly query programmed routes. - if r.ipVersion == 6 && (target.RouteType() == syscall.RTN_BLACKHOLE || target.RouteType() == syscall.RTN_THROW) { - route.LinkIndex = 1 +func (r *RouteTable) maybeCleanUpGracePeriods() { + if time.Since(r.lastGracePeriodCleanup) < r.routeCleanupGracePeriod { + return } + for k, v := range r.ifaceIndexToGraceInfo { + if time.Since(v.FirstSeen) < r.routeCleanupGracePeriod { + continue + } + if _, ok := r.ifaceIndexToName[k]; ok { + continue // Iface still exists, don't want to reset its grace period. + } + delete(r.ifaceIndexToGraceInfo, k) - if target.Src != nil { - route.Src = target.Src.AsNetIP() - } else if r.deviceRouteSourceAddress != nil { - route.Src = r.deviceRouteSourceAddress + r.livenessCallback() } +} - if target.GW != nil { - route.Gw = target.GW.AsNetIP() +func (r *RouteTable) maybeResyncWithDataplane() error { + nl, err := r.nl.Handle() + if err != nil { + r.logCxt.WithError(err).Error("Failed to connect to netlink.") + return ConnectFailed } - if target.Type == TargetTypeVXLAN || target.Type == TargetTypeNoEncap { - route.Scope = netlink.SCOPE_UNIVERSE - route.SetFlag(syscall.RTNH_F_ONLINK) + if r.fullResyncNeeded { + return r.doFullResync(nl) } - return route + // Do any partial per-interface resyncs. + return r.resyncIndividualInterfaces(nl) } -// fullResyncRoutesForLink performs a full resync of the routes by first listing current routes and correlating against -// the expected set. After correlation, it will create a set of routes to delete and update the delta routes to add -// back any missing routes. -func (r *RouteTable) fullResyncRoutesForLink(logCxt *log.Entry, ifaceName string, deletedConnCIDRs set.Set[ip.CIDR]) ([]netlink.Route, error) { - programmedRoutes, err := r.readProgrammedRoutes(logCxt, ifaceName) - if err != nil { - return nil, err - } +func (r *RouteTable) doFullResync(nl netlinkshim.Interface) error { + r.logCxt.Debug("Doing full resync.") + r.opReporter.RecordOperation(fmt.Sprint("resync-routes-v", r.ipVersion)) + resyncStartTime := time.Now() - var routesToDelete []netlink.Route - expectedTargets := r.ifaceNameToTargets[ifaceName] - pendingDeltaTargets := r.pendingIfaceNameToDeltaTargets[ifaceName] - if pendingDeltaTargets == nil { - pendingDeltaTargets = map[ip.CIDR]*Target{} - r.pendingIfaceNameToDeltaTargets[ifaceName] = pendingDeltaTargets - } - alreadyCorrectCIDRs := set.New[ip.CIDR]() - leaveDirty := false - for _, route := range programmedRoutes { - logCxt.Debugf("Processing route: %v %v %v", route.Table, route.LinkIndex, route.Dst) - var dest ip.CIDR - if route.Dst != nil { - dest = ip.CIDRFromIPNet(route.Dst) - } - logCxt := logCxt.WithField("dest", dest) - // Check if we should remove routes not added by us - if !r.removeExternalRoutes && route.Protocol != r.deviceRouteProtocol { - logCxt.Debug("Syncing routes: not removing route as it is not marked as Felix route") - continue - } + // It's possible that we get out of sync with the interface monitor; for example, if the + // RouteTable is created after start-of-day. Do our own refresh of the list of links. + if err := r.refreshAllIfaceStates(nl); err != nil { + log.WithError(err).Error("Failed to list interfaces") + return fmt.Errorf("failed to list interfaces during resync: %w", err) + } - expectedTarget, expectedTargetFound := expectedTargets[dest] - routeExpected := expectedTargetFound || (r.ipVersion == 6 && dest == ipV6LinkLocalCIDR) - var routeProblems []string - if !routeExpected { - routeProblems = append(routeProblems, "unexpected route") - } - if dest != ipV6LinkLocalCIDR { - expectedSrc := r.deviceRouteSourceAddress - if expectedTargetFound && expectedTarget.Src != nil { - expectedSrc = expectedTarget.Src.AsNetIP() - } - if !expectedSrc.Equal(route.Src) { - routeProblems = append(routeProblems, "incorrect source address") - } - if r.deviceRouteProtocol != route.Protocol { - routeProblems = append(routeProblems, "incorrect protocol") - } - if expectedTargetFound && expectedTarget.RouteType() != route.Type { - routeProblems = append(routeProblems, "incorrect type") + // Load all the routes in the routing table. For the main routing table, + // this will include non-Calico routes, which we'll filter out later. + routeFilter := &netlink.Route{ + Table: r.tableIndex, + } + routeFilterFlags := netlink.RT_FILTER_TABLE + + var err error + seenKeys := set.NewSize[kernelRouteKey](r.kernelRoutes.Dataplane().Len()) + for attempt := 0; attempt < routeListFilterAttempts; attempt++ { + // Using the Iter version here saves allocating a large slice of netlink.Route, + // which we immediately discard. + var scratchRoute netlink.Route + err = nl.RouteListFilteredIter(r.netlinkFamily, routeFilter, routeFilterFlags, func(route netlink.Route) bool { + // This copy avoids an alloc per iteration. We leak scratchRoute + // once but avoid leaking the function parameter. + scratchRoute = route + r.onIfaceSeen(route.LinkIndex) + + if !r.routeIsOurs(&scratchRoute) { + // Not a route that we're managing. + return true } - if (route.Gw == nil && expectedTarget.GW != nil) || - (route.Gw != nil && expectedTarget.GW == nil) || - (route.Gw != nil && expectedTarget.GW != nil && !route.Gw.Equal(expectedTarget.GW.AsNetIP())) { - routeProblems = append(routeProblems, "incorrect gateway") + + kernKey, kernRoute := r.netlinkRouteToKernelRoute(&scratchRoute) + if oldRoute, ok := r.kernelRoutes.Dataplane().Get(kernKey); !ok || oldRoute.Equals(kernRoute) { + r.kernelRoutes.Dataplane().Set(kernKey, kernRoute) } - } - if len(routeProblems) == 0 { - logCxt.Debug("Route is correct") - alreadyCorrectCIDRs.Add(dest) - continue - } - // In order to allow Calico to run without Felix in an emergency, the CNI plugin pre-adds - // the route to the interface. To avoid flapping the route when Felix sees the interface - // before learning about the endpoint, we give each interface a grace period after we first - // see it before we remove routes that we're not expecting. Check whether the grace period - // applies to this interface. - ifaceInGracePeriod := r.time.Since(r.ifaceNameToFirstSeen[ifaceName]) < r.routeCleanupGracePeriod - if ifaceInGracePeriod && !routeExpected { - // Don't remove unexpected routes from interfaces created recently. - logCxt.Info("Syncing routes: found unexpected route; ignoring due to grace period.") - leaveDirty = true + seenKeys.Add(kernKey) + r.livenessCallback() + return true + }) + if errors.Is(err, unix.EINTR) { + // Expected error if the routes got updated in kernel mid-dump. + log.WithError(err).Debug("Interrupted while listing routes.") + seenKeys.Clear() continue } - logCxt.WithField("routeProblems", routeProblems).Info("Remove old route") - routesToDelete = append(routesToDelete, route) - if dest != nil { - deletedConnCIDRs.Add(dest) - } + break } - // Now loop through the expected CIDRs to Target. Remove any that we did not find, and add them back into our - // delta updates (unless the entry is superseded by another update). - for cidr, target := range expectedTargets { - if alreadyCorrectCIDRs.Contains(cidr) { - continue - } - logCxt := logCxt.WithField("cidr", cidr) - logCxt.Debug("Deleting from expected targets") - delete(expectedTargets, cidr) - - // If we do not have an update that supersedes this entry, then add it back in as an update so that we add - // the route. - if pendingTarget, ok := pendingDeltaTargets[cidr]; !ok { - logCxt.Debug("No pending target update, adding back in as an update") - pendingDeltaTargets[cidr] = safeTargetPointer(target) - } else if pendingTarget == nil { - logCxt.Debug("Pending target deletion, removing delete update") - delete(pendingDeltaTargets, cidr) - } else { - logCxt.Debug("Pending target update, no changes to deltas required") - } + if errors.Is(err, unix.ENOENT) { + // In strict mode, get this if the routing table doesn't exist; it'll be auto-created + // when we add the first route so just treat it as empty. + log.WithError(err).Debug("Routing table doesn't exist (yet). Treating as empty.") + err = nil } - - if leaveDirty { - // Superfluous routes on a recently created interface. We'll recheck later. - return routesToDelete, IfaceGrace + if err != nil { + return fmt.Errorf("failed to list all routes for resync: %w", err) } - return routesToDelete, nil + r.kernelRoutes.Dataplane().Iter(func(kernKey kernelRouteKey, kernRoute kernelRoute) { + if !seenKeys.Contains(kernKey) { + r.kernelRoutes.Dataplane().Delete(kernKey) + r.conntrackTracker.OnDataplaneRouteDeleted(kernKey.CIDR, kernRoute.Ifindex) + } + r.livenessCallback() + }) + + // We're now in sync. + r.ifacesToRescan.Clear() + r.fullResyncNeeded = false + resyncTimeSummary.Observe(r.time.Since(resyncStartTime).Seconds()) + return nil } -func (r *RouteTable) readProgrammedRoutes(logCxt *log.Entry, ifaceName string) ([]netlink.Route, error) { - // Get the netlink client and the link attributes - nl, err := r.nl.Handle() - if err != nil { - logCxt.Debug("Failed to connect to netlink") - return nil, ConnectFailed +func (r *RouteTable) SetRemoveExternalRoutes(b bool) { + r.removeExternalRoutes = b +} + +func (r *RouteTable) resyncIndividualInterfaces(nl netlinkshim.Interface) error { + if r.ifacesToRescan.Len() == 0 { + return nil } - // Try to get the link. This may fail if it's been deleted out from under us. - linkAttrs, err := r.getLinkAttributes(ifaceName) + r.opReporter.RecordOperation(fmt.Sprint("partial-resync-routes-v", r.ipVersion)) + r.ifacesToRescan.Iter(func(ifaceName string) error { + r.livenessCallback() + err := r.resyncIface(nl, ifaceName) + if err != nil { + r.nl.MarkHandleForReopen() + return nil + } + return set.RemoveItem + }) + return nil +} + +// resyncIface checks the current state of a single interface and its routes. +// It updates the interface state and the dataplane side of the route +// DeltaTracker. Note: this method can trigger route recalculation, +// so it shouldn't be called while iterating over the DeltaTracker. For +// example, if the interface status check discovers the interface has gone +// down, that might trigger another route to become active, mutating the +// DeltaTracker. +func (r *RouteTable) resyncIface(nl netlinkshim.Interface, ifaceName string) error { + // We can be out of sync with the interface monitor if this + // RouteTable was created after start-of-day. Refresh the link. + startTime := time.Now() + err := r.refreshIfaceStateBestEffort(nl, ifaceName) if err != nil { - return nil, err + r.nl.MarkHandleForReopen() + return err } - // Got the link; try to sync its routes. Note: We used to check if the interface - // was oper down before we tried to do the sync but that prevented us from removing - // routes from an interface in some corner cases (such as being admin up but oper - // down). - routeFilter := &netlink.Route{ - Table: r.tableIndex, + ifIndex, ok := r.ifaceIndexForName(ifaceName) + if !ok { + r.logCxt.Debug("Ignoring rescan of unknown interface.") + return nil } - routeFilterFlags := netlink.RT_FILTER_OIF - if r.tableIndex != 0 { - routeFilterFlags |= netlink.RT_FILTER_TABLE - } - if linkAttrs != nil { - // Link attributes might be nil for the special "no-OIF" interface name. - routeFilter.LinkIndex = linkAttrs.Index - } else if r.ipVersion == 6 { - // IPv6 no-OIF interfaces get corrected to lo, which is interface index 1. - routeFilter.LinkIndex = 1 + routeFilter := &netlink.Route{ + Table: r.tableIndex, + LinkIndex: ifIndex, + } + routeFilterFlags := netlink.RT_FILTER_OIF | netlink.RT_FILTER_TABLE + + seenRoutes := set.New[kernelRouteKey]() + for attempt := 0; attempt < routeListFilterAttempts; attempt++ { + // Using the Iter version here saves allocating a large slice of netlink.Route, + // which we immediately discard. + var scratchRoute netlink.Route + err = nl.RouteListFilteredIter(r.netlinkFamily, routeFilter, routeFilterFlags, func(route netlink.Route) bool { + // This copy avoids an alloc per iteration. We leak scratchRoute + // once but avoid leaking the function parameter. + scratchRoute = route + + if !r.routeIsOurs(&scratchRoute) { + // Not a route that we're managing. + return true + } + + kernKey, kernRoute := r.netlinkRouteToKernelRoute(&scratchRoute) + if oldRoute, ok := r.kernelRoutes.Dataplane().Get(kernKey); !ok || oldRoute.Equals(kernRoute) { + r.kernelRoutes.Dataplane().Set(kernKey, kernRoute) + } + seenRoutes.Add(kernKey) + return true + }) + if errors.Is(err, unix.EINTR) { + // Expected error if the routes got updated in kernel mid-dump. + log.WithError(err).Debug("Interrupted while listing routes.") + seenRoutes.Clear() + continue + } + break } - programmedRoutes, err := nl.RouteListFiltered(r.netlinkFamily, routeFilter, routeFilterFlags) + if errors.Is(err, unix.ENOENT) { // In strict mode, get this if the routing table doesn't exist; it'll be auto-created // when we add the first route so just treat it as empty. log.WithError(err).Debug("Routing table doesn't exist (yet). Treating as empty.") err = nil - programmedRoutes = nil } - r.livenessCallback() if err != nil { // Filter the error so that we don't spam errors if the interface is being torn // down. filteredErr := r.filterErrorByIfaceState(ifaceName, err, ListFailed, false) - if filteredErr == ListFailed { - logCxt.WithError(err).WithFields(log.Fields{ + if errors.Is(filteredErr, ListFailed) { + r.logCxt.WithError(err).WithFields(log.Fields{ + "iface": ifaceName, "routeFilter": routeFilter, "flags": routeFilterFlags, }).Error("Error listing routes") - r.nl.MarkHandleForReopen() // Defensive: force a netlink reconnection next time. + r.nl.MarkHandleForReopen() + return nil } else { - logCxt.WithError(err).Info("Failed to list routes; interface down/gone.") + r.logCxt.WithError(filteredErr).WithField("iface", ifaceName).Debug( + "Failed to list routes; interface down/gone.") + return nil + } + } + + // Look for routes that the tracker says are there but are actually missing. + for _, ifaceToRoutes := range r.ifaceToRoutes { + for cidr := range ifaceToRoutes[ifaceName] { + kernKey := r.routeKeyForCIDR(cidr) + if seenRoutes.Contains(kernKey) { + // Route still there; handled above. + continue + } + desKernRoute, ok := r.kernelRoutes.Desired().Get(kernKey) + if !ok || desKernRoute.Ifindex != ifIndex { + // The interface we're syncing doesn't own this route + // so the fact that it's missing is expected. + continue + } + r.kernelRoutes.Dataplane().Delete(kernKey) } - return nil, filteredErr } - return programmedRoutes, nil + partialResyncTimeSummary.Observe(r.time.Since(startTime).Seconds()) + + return nil } -// startConntrackDeletion starts the deletion of conntrack entries for the given CIDR in the background. Pending -// deletions are tracked in the pendingConntrackCleanups map so we can block waiting for them later. -// -// It's important to do the conntrack deletions in the background because scanning the conntrack -// table is very slow if there are a lot of entries. Previously, we did the deletion synchronously -// but that led to lengthy Apply() calls on the critical path. -func (r *RouteTable) startConntrackDeletion(ipAddr ip.Addr) { - log.WithField("ip", ipAddr).Debug("Starting goroutine to delete conntrack entries") - done := make(chan struct{}) - r.pendingConntrackCleanups[ipAddr] = done - go func() { - defer close(done) - r.conntrack.RemoveConntrackFlows(r.ipVersion, ipAddr.AsNetIP()) - log.WithField("ip", ipAddr).Debug("Deleted conntrack entries") - }() +func (r *RouteTable) refreshAllIfaceStates(nl netlinkshim.Interface) error { + debug := log.IsLevelEnabled(log.DebugLevel) + + links, err := nl.LinkList() + if err != nil { + return err + } + seenNames := set.New[string]() + + // First pass, simulate deletions of any interfaces that have been + // renamed or renumbered. + for _, link := range links { + oldIdx, ok := r.ifaceNameToIndex[link.Attrs().Name] + if ok && oldIdx != link.Attrs().Index { + // Interface renumbered. For example, deleted and then recreated. + // Simulate a deletion of the old interface. + log.WithFields(log.Fields{ + "ifaceName": link.Attrs().Name, + "oldIdx": oldIdx, + "newIdx": link.Attrs().Index, + }).Info("Spotted interface had changed index during resync.") + r.OnIfaceStateChanged(link.Attrs().Name, oldIdx, ifacemonitor.StateNotPresent) + } + oldName, ok := r.ifaceIndexToName[link.Attrs().Index] + if ok && oldName != link.Attrs().Name { + // Interface renamed. Simulate a deletion of the old interface. + log.WithFields(log.Fields{ + "ifaceName": link.Attrs().Name, + "oldName": oldName, + "newName": link.Attrs().Name, + }).Info("Spotted interface had changed name during resync.") + r.OnIfaceStateChanged(oldName, link.Attrs().Index, ifacemonitor.StateNotPresent) + } + r.livenessCallback() + } + + // Second pass, update the state of any changed interfaces. + for _, link := range links { + seenNames.Add(link.Attrs().Name) + newState := ifacemonitor.StateDown + if ifacemonitor.LinkIsOperUp(link) { + newState = ifacemonitor.StateUp + } + oldState := r.ifaceIndexToState[link.Attrs().Index] + log.WithFields(log.Fields{ + "ifaceName": link.Attrs().Name, + "newState": newState, + "oldState": oldState, + "idx": link.Attrs().Index, + }).Debug("Checking interface state.") + if newState != oldState { + // Only call OnIfaceStateChanged if the state has actually changed + // so that we avoid triggering it to re-do conflict resolution + // (which will generate log spam if the interface hasn't changed). + if debug { + r.logCxt.WithFields(log.Fields{ + "ifaceName": link.Attrs().Name, + "oldState": oldState, + "newState": newState, + }).Debug("Spotted interface had changed state during resync.") + } + r.OnIfaceStateChanged(link.Attrs().Name, link.Attrs().Index, newState) + } + r.livenessCallback() + } + + // Third pass, remove any interfaces that have disappeared. + for name := range r.ifaceNameToIndex { + if seenNames.Contains(name) { + continue + } + if debug { + r.logCxt.WithField("ifaceName", name).Info("Spotted interface not present during full resync. Cleaning up.") + } + r.OnIfaceStateChanged(name, 0, ifacemonitor.StateNotPresent) + r.livenessCallback() + } + return nil +} + +func (r *RouteTable) refreshIfaceStateBestEffort(nl netlinkshim.Interface, ifaceName string) error { + r.logCxt.WithField("name", ifaceName).Debug("Refreshing state of interface.") + link, err := nl.LinkByName(ifaceName) + var lnf netlink.LinkNotFoundError + if errors.As(err, &lnf) { + r.OnIfaceStateChanged(ifaceName, 0, ifacemonitor.StateNotPresent) + return nil + } else if err != nil { + log.WithError(err).Warn("Failed to get link.") + return fmt.Errorf("failed to look up interface: %w", err) + } + state := ifacemonitor.StateDown + if ifacemonitor.LinkIsOperUp(link) { + state = ifacemonitor.StateUp + } + r.OnIfaceStateChanged(link.Attrs().Name, link.Attrs().Index, state) + return nil +} + +func (r *RouteTable) routeKeyForCIDR(cidr ip.CIDR) kernelRouteKey { + return kernelRouteKey{CIDR: cidr} } -// cleanUpPendingConntrackDeletions scans the pendingConntrackCleanups map for completed entries and removes them. -func (r *RouteTable) cleanUpPendingConntrackDeletions() { - for ipAddr, c := range r.pendingConntrackCleanups { - select { - case <-c: - log.WithField("ip", ipAddr).Debug( - "Background goroutine finished deleting conntrack entries") - delete(r.pendingConntrackCleanups, ipAddr) - default: - log.WithField("ip", ipAddr).Debug( - "Background goroutine yet to finish deleting conntrack entries") +func (r *RouteTable) routeIsOurs(route *netlink.Route) bool { + // We're on the hot path, so it's worth avoiding the overheads of + // WithField(s) if debug is disabled. + logCxt := r.logCxt + if log.IsLevelEnabled(log.DebugLevel) { + logCxt = logCxt.WithField("route", route) + } + ifaceName := "" + if routeIsSpecialNoIfRoute(route) { + ifaceName = InterfaceNone + } else if routeIsIPv6Bootstrap(route) { + logCxt.Debug("Ignoring IPv6 bootstrap route, kernel manages these.") + return false + } else { + ifaceName = r.ifaceIndexToName[route.LinkIndex] + if ifaceName == "" { + // We don't know about this interface. Either we're racing + // with link creation, in which case we'll hear about the + // interface soon and work out what to do, or we're seeing + // a route for a just-deleted interface, in which case + // we don't care. + logCxt.Debug("Ignoring route for unknown iface") + return false + } + } + + if !r.ownershipPolicy.RouteIsOurs(ifaceName, route) { + logCxt.Debug("Ignoring route (it doesn't belong to us).") + return false + } + return true +} + +func (r *RouteTable) netlinkRouteToKernelRoute(route *netlink.Route) (kernKey kernelRouteKey, kernRoute kernelRoute) { + // Defensive; recent versions of netlink always return a CIDR, but just + // in case that gets regressed... + cidr := ip.CIDRFromIPNet(route.Dst) + if route.Dst == nil { + if r.ipVersion == 4 { + cidr = defaultCIDRv4 + } else { + cidr = defaultCIDRv6 + } + } + + kernKey = kernelRouteKey{ + CIDR: cidr, + Priority: route.Priority, + TOS: route.Tos, + } + kernRoute = kernelRoute{ + Type: route.Type, + Scope: route.Scope, + Src: ip.FromNetIP(route.Src), + OnLink: route.Flags&unix.RTNH_F_ONLINK != 0, + Protocol: route.Protocol, + } + + if len(route.MultiPath) > 0 { + // Multi-path route. + for _, nh := range route.MultiPath { + if nh.Flags&unix.RTNH_F_ONLINK != 0 { + kernRoute.OnLink = true + } + kernRoute.NextHops = append(kernRoute.NextHops, kernelNextHop{ + GW: ip.FromNetIP(nh.Gw), + Ifindex: nh.LinkIndex, + }) + } + } else { + // Single-path route. + kernRoute.GW = ip.FromNetIP(route.Gw) + kernRoute.Ifindex = route.LinkIndex + } + + if log.IsLevelEnabled(log.DebugLevel) { + r.logCxt.WithFields(log.Fields{ + "kernRoute": kernRoute, + "kernKey": kernKey, + }).Debug("Loaded route from kernel.") + } + return +} + +func routeIsIPv6Bootstrap(route *netlink.Route) bool { + if route.Dst == nil { + return false + } + if route.Family != netlink.FAMILY_V6 { + return false + } + return ip.CIDRFromIPNet(route.Dst) == ipV6LinkLocalCIDR +} + +func routeIsSpecialNoIfRoute(route *netlink.Route) bool { + if route.LinkIndex > 1 { + // Special routes either have 0 for the link index or 1 ('lo'), + // depending on IP version. + return false + } + if len(route.MultiPath) > 0 { + return true + } + switch route.Type { + case unix.RTN_LOCAL, unix.RTN_THROW, unix.RTN_BLACKHOLE, unix.RTN_PROHIBIT, unix.RTN_UNREACHABLE: + return true + } + return false +} + +func (r *RouteTable) applyUpdates(attempt int) error { + nl, err := r.nl.Handle() + if err != nil { + r.logCxt.Debug("Failed to connect to netlink") + return ConnectFailed + } + + // First clean up any old routes. + deletionErrs := map[kernelRouteKey]error{} + r.kernelRoutes.PendingDeletions().Iter(func(kernKey kernelRouteKey) deltatracker.IterAction { + r.livenessCallback() + kernRoute, _ := r.kernelRoutes.PendingDeletions().Get(kernKey) + if r.ifaceInGracePeriod(kernRoute.Ifindex) { + // Don't remove unexpected routes from interfaces created recently. + r.logCxt.WithFields(log.Fields{ + "route": kernRoute, + "dest": kernKey, + }).Debug("Found unexpected route; ignoring due to grace period.") + return deltatracker.IterActionNoOp + } + + err := r.deleteRoute(nl, kernKey) + if err != nil { + deletionErrs[kernKey] = err + return deltatracker.IterActionNoOp + } + r.conntrackTracker.OnDataplaneRouteDeleted(kernKey.CIDR, kernRoute.Ifindex) + + // Route is gone, clean up the dataplane side of the tracker. + r.logCxt.WithField("route", kernKey).Debug("Deleted route.") + return deltatracker.IterActionUpdateDataplane + }) + + // Now do a first pass of the routes that we want to create/update and + // trigger any necessary conntrack cleanups for moved routes. + r.kernelRoutes.PendingUpdates().Iter(func(kernKey kernelRouteKey, kernRoute kernelRoute) deltatracker.IterAction { + r.livenessCallback() + cidr := kernKey.CIDR + dataplaneRoute, dataplaneExists := r.kernelRoutes.Dataplane().Get(kernKey) + if dataplaneExists && r.conntrackTracker.CIDRNeedsEarlyCleanup(cidr, dataplaneRoute.Ifindex) { + err := r.deleteRoute(nl, kernKey) + if err != nil { + deletionErrs[kernKey] = err + return deltatracker.IterActionNoOp + } + // This will queue the route for conntrack cleanup. + r.conntrackTracker.OnDataplaneRouteDeleted(kernKey.CIDR, dataplaneRoute.Ifindex) + } + return deltatracker.IterActionNoOp + }) + + // Start any deferred conntrack cleanups and reset the tracking for next + // time. + r.conntrackTracker.StartConntrackCleanupAndReset() + + updateErrs := map[kernelRouteKey]error{} + r.kernelRoutes.PendingUpdates().Iter(func(kernKey kernelRouteKey, kRoute kernelRoute) deltatracker.IterAction { + r.livenessCallback() + dst := kernKey.CIDR.ToIPNet() + flags := 0 + if kRoute.OnLink { + flags = unix.RTNH_F_ONLINK + } + + // In case we're moving a route, wait for the cleanup to finish. + r.conntrackTracker.WaitForPendingDeletion(kernKey.CIDR) + + nlRoute := &netlink.Route{ + Family: r.netlinkFamily, + + Table: r.tableIndex, + Dst: &dst, + Tos: kernKey.TOS, + Priority: int(kernKey.Priority), + + Type: kRoute.Type, + Scope: kRoute.Scope, + Gw: kRoute.GWAsNetIP(), + Src: kRoute.SrcAsNetIP(), + LinkIndex: kRoute.Ifindex, + Protocol: kRoute.Protocol, + Flags: flags, + } + for _, nh := range kRoute.NextHops { + nlRoute.MultiPath = append(nlRoute.MultiPath, &netlink.NexthopInfo{ + LinkIndex: nh.Ifindex, + Gw: nh.GWAsNetIP(), + Flags: flags, + }) + } + r.logCxt.WithFields(log.Fields{ + "nlRoute": nlRoute, + "ourKey": kernKey, + "ourRoute": kRoute, + }).Debug("Replacing route") + err := nl.RouteReplace(nlRoute) + if err != nil { + name, ok := r.ifaceNameForIndex(kRoute.Ifindex) + if ok { + err = r.filterErrorByIfaceState( + name, + err, + err, + attempt == 0, + ) + + if errors.Is(err, IfaceDown) || errors.Is(err, IfaceNotPresent) { + // Very common race: the interface was taken down/deleted + // by the CNI plugin while we were trying to update it. + // Mark for a lazy rescan so that we won't try to program + // this route again next time (unless the interface shows + // up). + r.ifacesToRescan.Add(name) + return deltatracker.IterActionNoOp + } + err = fmt.Errorf("%v(%s): %w", kRoute, name, err) + } + + updateErrs[kernKey] = err + return deltatracker.IterActionNoOp + } + + // Route is updated, clean up the dataplane side of the tracker. + return deltatracker.IterActionUpdateDataplane + }) + + arpErrs := map[string]error{} + for ifaceName, addrToMAC := range r.pendingARPs { + // Add static ARP entries (for workload endpoints). This may have been + // needed at one point but it no longer seems to be required. Leaving + // it here for two reasons: (1) there may be an obscure scenario where + // it is needed. (2) we have tests that monitor netlink, and they break + // if it is removed because they see the ARP traffic. + ifaceIdx, ok := r.ifaceIndexForName(ifaceName) + if !ok { + // Asked to add ARP entries but the interface isn't known (yet). + // Leave them pending. We'll clean up the pending set if the + // datastore stops asking us to add ARP entries for this interface. continue } + for addr, mac := range addrToMAC { + r.livenessCallback() + err := r.addStaticARPEntry(nl, addr, mac, ifaceIdx) + if err != nil { + err = r.filterErrorByIfaceState( + ifaceName, + err, + err, + attempt == 0, + ) + + if errors.Is(err, IfaceDown) || errors.Is(err, IfaceNotPresent) { + // Very common race: the interface was taken down/deleted + // by the CNI plugin while we were trying to update it. + // Mark for a lazy rescan so that we won't try to program + // this route again next time (unless the interface shows + // up). + r.ifacesToRescan.Add(ifaceName) + err = nil + } + } + if err != nil { + log.WithError(err).Debug("Failed to add neighbor entry.") + arpErrs[fmt.Sprintf("%s/%s", ifaceName, addr)] = err + } else { + delete(addrToMAC, addr) + } + } + if len(addrToMAC) == 0 { + delete(r.pendingARPs, ifaceName) + } } + + err = nil + if len(deletionErrs) > 0 { + r.logCxt.WithField("errors", formatErrMap(deletionErrs)).Warn( + "Encountered some errors when trying to delete old routes.") + err = UpdateFailed + } + if len(updateErrs) > 0 { + r.logCxt.WithField("errors", formatErrMap(updateErrs)).Warn( + "Encountered some errors when trying to update routes. Will retry.") + err = UpdateFailed + } + if len(arpErrs) > 0 { + r.logCxt.WithField("errors", formatErrMap(arpErrs)).Warn( + "Encountered some errors when trying to add static ARP entries. Will retry.") + err = UpdateFailed + } + + return err } -// waitForPendingConntrackDeletion waits for any pending conntrack deletions (if any) for the given IP to complete. -func (r *RouteTable) waitForPendingConntrackDeletion(ipAddr ip.Addr) { - if c := r.pendingConntrackCleanups[ipAddr]; c != nil { - log.WithField("ip", ipAddr).Info("Waiting for pending conntrack deletion to finish") - <-c - log.WithField("ip", ipAddr).Info("Done waiting for pending conntrack deletion to finish") - delete(r.pendingConntrackCleanups, ipAddr) +// formatErrMap formats a map of errors as a string, ensuring the error +// messages are included in the output. +func formatErrMap[K comparable](errs map[K]error) string { + parts := make([]string, 0, len(errs)) + for k, v := range errs { + parts = append(parts, fmt.Sprintf("%v: %s", k, v.Error())) + } + return strings.Join(parts, ", ") +} + +func (r *RouteTable) ifaceInGracePeriod(ifindex int) bool { + graceInf, ok := r.ifaceIndexToGraceInfo[ifindex] + if !ok { + return false } + if graceInf.GraceExpired { + return false + } + name, ok := r.ifaceNameForIndex(ifindex) + if !ok { + return false + } + if !r.ownershipPolicy.IfaceShouldHaveGracePeriod(name) { + return false + } + return r.time.Since(graceInf.FirstSeen) < r.routeCleanupGracePeriod +} + +func (r *RouteTable) deleteRoute(nl netlinkshim.Interface, kernKey kernelRouteKey) error { + // Template route for deletion. The family, table, TOS, Priority uniquely + // identify the route, but we also need to set some fields to their "wildcard" + // values (found via code reading the kernel and running "ip route del" under + // strace). + dst := kernKey.CIDR.ToIPNet() + nlRoute := &netlink.Route{ + Family: r.netlinkFamily, + + Table: r.tableIndex, + Dst: &dst, + Tos: kernKey.TOS, + Priority: kernKey.Priority, + + Protocol: unix.RTPROT_UNSPEC, // Wildcard (but also zero value). + Scope: unix.RT_SCOPE_NOWHERE, // Wildcard. Note: non-zero value! + Type: unix.RTN_UNSPEC, // Wildcard (but also zero value). + } + err := nl.RouteDel(nlRoute) + if errors.Is(err, unix.ESRCH) { + r.logCxt.WithField("route", kernKey).Debug("Tried to delete route but it wasn't found.") + err = nil // Already gone (we hope). + } + return err } // filterErrorByIfaceState checks the current state of the interface; if it's down or gone, it // returns IfaceDown or IfaceNotPresent, otherwise, it returns the given defaultErr. -func (r *RouteTable) filterErrorByIfaceState(ifaceName string, currentErr, defaultErr error, suppressExistsWarning bool) error { +func (r *RouteTable) filterErrorByIfaceState( + ifaceName string, + currentErr, defaultErr error, + suppressExistsWarning bool, +) error { + if currentErr == nil { + return nil + } + logCxt := r.logCxt.WithFields(log.Fields{"ifaceName": ifaceName, "error": currentErr}) if ifaceName == InterfaceNone { // Short circuit the no-OIF interface name. - logCxt.Info("No interface on route.") + logCxt.Debug("No interface on route.") return defaultErr } @@ -1035,9 +1608,16 @@ func (r *RouteTable) filterErrorByIfaceState(ifaceName string, currentErr, defau // Current error already tells us that the link was not present. If we re-check // the status in this case, we open a race where the interface gets created and // we log an error when we're about to re-trigger programming anyway. - logCxt.Info("Failed to access interface because it doesn't exist.") + logCxt.Debug("Interface doesn't exist, perhaps workload is being torn down?") return IfaceNotPresent } + + if errors.Is(currentErr, syscall.ENETDOWN) { + // Another clear error: interface is down. + logCxt.Debug("Interface down, perhaps workload is being torn down?") + return IfaceDown + } + // If the current error wasn't clear, try to look up the interface to see if there's a // well-understood reason for the failure. nl, err := r.nl.Handle() @@ -1058,7 +1638,7 @@ func (r *RouteTable) filterErrorByIfaceState(ifaceName string, currentErr, defau "Failed to access interface but it appears to be up; retrying...") } else { logCxt.WithField("link", link).Warning( - "Failed to access interface but it appears to be up") + "Failed to access interface but it appears to be up?") } return defaultErr } else { @@ -1094,49 +1674,177 @@ func isNotFoundError(err error) bool { return false } -// getLinkAttributes returns the link attributes for the specified link name. This method returns nil if the -// interface name is the special "no-OIF" name. -func (r *RouteTable) getLinkAttributes(ifaceName string) (*netlink.LinkAttrs, error) { - if ifaceName == InterfaceNone { - // Short circuit the no-OIF interface name. - return nil, nil - } +func (r *RouteTable) addStaticARPEntry( + nl netlinkshim.Interface, + addr ip.Addr, + mac net.HardwareAddr, + ifindex int, +) error { + a := &netlink.Neigh{ + Family: unix.AF_INET, + LinkIndex: ifindex, + State: netlink.NUD_PERMANENT, + Type: unix.RTN_UNICAST, + IP: addr.AsNetIP(), + HardwareAddr: mac, + } + if log.IsLevelEnabled(log.DebugLevel) { + r.logCxt.WithField("entry", a).Debug("Adding static ARP entry.") + } + return nl.NeighSet(a) +} - // Try to get the link. This may fail if it's been deleted out from under us. - logCxt := r.logCxt.WithField("ifaceName", ifaceName) +func (r *RouteTable) updateGauges() { + r.gaugeNumRoutes.Set(float64(r.kernelRoutes.Desired().Len())) + r.gaugeNumIfaces.Set(float64(len(r.ifaceIndexToName))) +} - nl, err := r.nl.Handle() - if err != nil { - r.logCxt.WithError(err).Error("Failed to connect to netlink, retrying...") - return nil, ConnectFailed +func (r *RouteTable) checkTargets(ifaceName string, targets ...Target) { + for _, t := range targets { + if len(t.MultiPath) > 0 { + if t.GW != nil || ifaceName != InterfaceNone { + log.Panic("MultiPath routes should have InterfaceNone and no GW") + } + r.haveMultiPathRoutes = true + for _, nh := range t.MultiPath { + if nh.Gw == nil { + log.Panic("MultiPath route should have GW") + } + if nh.IfaceName == "" || nh.IfaceName == InterfaceNone { + log.Panic("MultiPath route should have interface name") + } + } + } } +} - link, err := nl.LinkByName(ifaceName) - if err != nil { - // Filter the error so that we don't spam errors if the interface is being torn - // down. - filteredErr := r.filterErrorByIfaceState(ifaceName, err, GetFailed, false) - if filteredErr == GetFailed { - logCxt.WithError(err).Error("Failed to get interface.") - r.nl.MarkHandleForReopen() // Defensive: force a netlink reconnection next time. - } else { - logCxt.WithError(err).Info("Failed to get interface; it's down/gone.") +// kernelRouteKey represents the kernel's FIB key. The kernel allows routes +// to coexist as long as they have different keys. +type kernelRouteKey struct { + // Destination CIDR; route matches traffic to this destination. + CIDR ip.CIDR + // TOS is the Type-of-Service field. For example, one app may mark its + // packets as "high importance" and that will take a different route to + // another app. + // + // Kernel uses the TOS=0 route if there isn't a more precise match. + TOS int + // Priority is the routing metric / distance. Given two routes with the + // same CIDR, the kernel prefers the route with the _lower_ priority. + Priority int +} + +func (k kernelRouteKey) String() string { + return fmt.Sprintf("%s(tos=%x metric=%d)", k.CIDR.String(), k.TOS, k.Priority) +} + +// kernelRoute is our low-level representation of the parts of a route that +// we care to program. It contains fields that we can easily read back from the +// kernel for comparison. In particular, we track the interface index instead +// of the interface name. This means that if an interface is recreated, we +// must trigger recalculation of the desired kernelRoute. +type kernelRoute struct { + Type int // unix.RTN_... constants. + Scope netlink.Scope + Src ip.Addr + Protocol netlink.RouteProtocol + OnLink bool + + // Either GW and Ifindex should be specified (for a gateway route) or + // NextHops should be specified (for a multi-path route). + GW ip.Addr + Ifindex int + + NextHops []kernelNextHop +} + +func (r kernelRoute) IsZero() bool { + var zero kernelRoute + return r.Equals(zero) +} + +func (r kernelRoute) Equals(b kernelRoute) bool { + if r.Type != b.Type { + return false + } + if r.Scope != b.Scope { + return false + } + if r.Src != b.Src { + return false + } + if r.Protocol != b.Protocol { + return false + } + if r.OnLink != b.OnLink { + return false + } + if r.GW != b.GW { + return false + } + if r.Ifindex != b.Ifindex { + return false + } + if len(r.NextHops) != len(b.NextHops) { + return false + } + for i := range r.NextHops { + if r.NextHops[i].GW != b.NextHops[i].GW { + return false + } + if r.NextHops[i].Ifindex != b.NextHops[i].Ifindex { + return false } - return nil, filteredErr } - return link.Attrs(), nil + return true } -func (r *RouteTable) shouldDeleteConflictingRoutes() bool { - gate := r.featureDetector.FeatureGate("DeleteConflictingRoutes") - switch strings.ToLower(gate) { - case "enabled": // Default to disabled. - return true +func (r kernelRoute) GWAsNetIP() net.IP { + if r.GW == nil { + return nil } - return false + return r.GW.AsNetIP() } -// safeTargetPointer returns a pointer to a Target safely ensuring the pointer is unique. -func safeTargetPointer(target Target) *Target { - return &target +func (r kernelRoute) SrcAsNetIP() net.IP { + if r.Src == nil { + return nil + } + return r.Src.AsNetIP() +} + +func (r kernelRoute) String() string { + if r.IsZero() { + return "" + } + srcStr := "" + if r.Src != nil { + srcStr = r.Src.String() + } + + nextHopPart := "" + if len(r.NextHops) > 0 { + nextHopPart = fmt.Sprintf("NextHops=%v", r.NextHops) + } else { + gwStr := "" + if r.GW != nil { + gwStr = r.GW.String() + } + nextHopPart = fmt.Sprintf("GW=%s, Ifindex=%d", gwStr, r.Ifindex) + } + + return fmt.Sprintf("kernelRoute{Type=%d, Scope=%d, Src=%s, Protocol=%v, OnLink=%v, %s}", + r.Type, r.Scope, srcStr, r.Protocol, r.OnLink, nextHopPart) +} + +type kernelNextHop struct { + GW ip.Addr + Ifindex int +} + +func (h kernelNextHop) GWAsNetIP() net.IP { + if h.GW == nil { + return nil + } + return h.GW.AsNetIP() } diff --git a/felix/routetable/route_table_test.go b/felix/routetable/route_table_test.go index 9cf2aa7bcc4..7a5d8fb7408 100644 --- a/felix/routetable/route_table_test.go +++ b/felix/routetable/route_table_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,19 +15,19 @@ package routetable_test import ( - "golang.org/x/sys/unix" - - "github.com/projectcalico/calico/felix/logutils" - . "github.com/projectcalico/calico/felix/routetable" - "fmt" "net" "syscall" "time" + "golang.org/x/sys/unix" + + "github.com/projectcalico/calico/felix/logutils" + . "github.com/projectcalico/calico/felix/routetable" + "github.com/projectcalico/calico/felix/routetable/ownershippol" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" "github.com/projectcalico/calico/felix/ifacemonitor" @@ -46,6 +46,14 @@ var ( ip1 = ip.MustParseCIDROrIP("10.0.0.1/32").ToIPNet() ip2 = ip.MustParseCIDROrIP("10.0.0.2/32").ToIPNet() ip13 = ip.MustParseCIDROrIP("10.0.1.3/32").ToIPNet() + + defaultOwnershipPolicy = ownershippol.MainTableOwnershipPolicy{ + WorkloadInterfacePrefixes: []string{"cali"}, + RemoveNonCalicoWorkloadRoutes: true, + CalicoSpecialInterfaces: nil, + AllRouteProtocols: []netlink.RouteProtocol{FelixRouteProtocol, 80}, + ExclusiveRouteProtocols: []netlink.RouteProtocol{80}, + } ) var _ = Describe("RouteTable v6", func() { @@ -57,20 +65,19 @@ var _ = Describe("RouteTable v6", func() { dataplane = mocknetlink.New() t = mocktime.New() // No grace period set, so invalid routes should be deleted immediately on apply. - rt = NewWithShims( - []string{"^cali.*"}, + rt = New( + &defaultOwnershipPolicy, 6, - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, nil, FelixRouteProtocol, true, 0, logutils.NewSummarizer("test"), dataplane, + WithTimeShim(t), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }) @@ -78,10 +85,31 @@ var _ = Describe("RouteTable v6", func() { Expect(rt).ToNot(BeNil()) }) + It("should use interface index 1 for no-iface routes", func() { + rt.RouteUpdate(RouteClassWireguard, InterfaceNone, Target{ + CIDR: ip.MustParseCIDROrIP("f00f::/128"), + Type: TargetTypeThrow, + }) + err := rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute["254-f00f::/128"]).To(Equal( + netlink.Route{ + Family: netlink.FAMILY_V6, + LinkIndex: 1, + Dst: mustParseCIDR("f00f::/128"), + Type: syscall.RTN_THROW, + Protocol: syscall.RTPROT_BOOT, + Scope: netlink.SCOPE_UNIVERSE, + Table: unix.RT_TABLE_MAIN, + }, + )) + }) + It("should not remove the IPv6 link local route", func() { // Route that should be left alone noopLink := dataplane.AddIface(4, "cali4", true, true) noopRoute := netlink.Route{ + Family: netlink.FAMILY_V6, LinkIndex: noopLink.LinkAttrs.Index, Dst: mustParseCIDR("fe80::/64"), Type: syscall.RTN_UNICAST, @@ -89,7 +117,7 @@ var _ = Describe("RouteTable v6", func() { Scope: netlink.SCOPE_LINK, Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(noopLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, noopLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.4/32"), DestMAC: mac1}, }) dataplane.AddMockRoute(&noopRoute) @@ -125,14 +153,10 @@ var _ = Describe("RouteTable", func() { // Setting an auto-increment greater than the route cleanup delay effectively // disables the grace period for these tests. t.SetAutoIncrement(11 * time.Second) - rt = NewWithShims( - []string{"^cali.*"}, + rt = New( + &defaultOwnershipPolicy, 4, - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, nil, FelixRouteProtocol, true, @@ -140,6 +164,10 @@ var _ = Describe("RouteTable", func() { logutils.NewSummarizer("test"), dataplane, WithRouteCleanupGracePeriod(10*time.Second), + WithStaticARPEntries(true), + WithTimeShim(t), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }) @@ -149,14 +177,14 @@ var _ = Describe("RouteTable", func() { It("should handle unexpected non-calico interface updates", func() { t.SetAutoIncrement(0 * time.Second) - rt.OnIfaceStateChanged("calx", ifacemonitor.StateUp) + rt.OnIfaceStateChanged("calx", 11, ifacemonitor.StateUp) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) }) It("should handle unexpected calico interface updates", func() { t.SetAutoIncrement(0 * time.Second) - rt.OnIfaceStateChanged("cali1", ifacemonitor.StateUp) + rt.OnIfaceStateChanged("cali1", 12, ifacemonitor.StateUp) rt.QueueResync() err := rt.Apply() Expect(err).ToNot(HaveOccurred()) @@ -175,6 +203,7 @@ var _ = Describe("RouteTable", func() { cali2 = dataplane.AddIface(4, "cali2", true, true) cali3 = dataplane.AddIface(5, "cali3", true, true) cali1Route = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali1.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.1/32"), Type: syscall.RTN_UNICAST, @@ -184,6 +213,7 @@ var _ = Describe("RouteTable", func() { } dataplane.AddMockRoute(&cali1Route) cali3Route = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.3/32"), Type: syscall.RTN_UNICAST, @@ -193,6 +223,7 @@ var _ = Describe("RouteTable", func() { } dataplane.AddMockRoute(&cali3Route) gatewayRoute = netlink.Route{ + Family: unix.AF_INET, LinkIndex: eth0.LinkAttrs.Index, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, @@ -245,6 +276,7 @@ var _ = Describe("RouteTable", func() { It("Should clear out a source address when source address is not set", func() { updateLink := dataplane.AddIface(6, "cali5", true, true) updateRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: updateLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.5/32"), Type: syscall.RTN_UNICAST, @@ -254,7 +286,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, } dataplane.AddMockRoute(&updateRoute) - rt.SetRoutes(updateLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, updateLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1}, }) @@ -268,23 +300,23 @@ var _ = Describe("RouteTable", func() { }) Describe("With a device route source address set", func() { deviceRouteSource := "192.168.0.1" - deviceRouteSourceAddress := net.ParseIP(deviceRouteSource) + deviceRouteSourceAddress := net.ParseIP(deviceRouteSource).To4() // Modify the route table to have the device route source address set BeforeEach(func() { - rt = NewWithShims( - []string{"^cali.*"}, + rt = New( + &defaultOwnershipPolicy, 4, - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, deviceRouteSourceAddress, FelixRouteProtocol, true, 0, logutils.NewSummarizer("test"), dataplane, + WithTimeShim(t), + WithStaticARPEntries(true), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }) It("Should delete routes without a source address", func() { @@ -301,35 +333,73 @@ var _ = Describe("RouteTable", func() { It("Should add routes with a source address", func() { // Route that needs to be added addLink := dataplane.AddIface(6, "cali6", true, true) - rt.SetRoutes(addLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, addLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.6"), DestMAC: mac1}, }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) + cidr := mustParseCIDR("10.0.0.6/32") Expect(dataplane.RouteKeyToRoute["254-10.0.0.6/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: addLink.LinkAttrs.Index, - Dst: mustParseCIDR("10.0.0.6/32"), + Dst: cidr, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, Scope: netlink.SCOPE_LINK, Src: deviceRouteSourceAddress, Table: unix.RT_TABLE_MAIN, })) - Expect(dataplane.HasStaticArpEntry(ip.MustParseCIDROrIP("10.0.0.6/32"), mac1, "cali6")).To(BeTrue()) + dataplane.ExpectNeighs(unix.AF_INET, netlink.Neigh{ + Family: unix.AF_INET, + LinkIndex: addLink.LinkAttrs.Index, + State: netlink.NUD_PERMANENT, + Type: unix.RTN_UNICAST, + IP: cidr.IP, + HardwareAddr: mac1, + }) + }) + It("Should skip adding an ARP entry if route is deleted via SetRoutes before sync", func() { + // Route that needs to be added + link := dataplane.AddIface(6, "cali6", true, true) + rt.SetRoutes(RouteClassLocalWorkload, link.LinkAttrs.Name, []Target{ + {CIDR: ip.MustParseCIDROrIP("10.0.0.6"), DestMAC: mac1}, + }) + rt.SetRoutes(RouteClassLocalWorkload, link.LinkAttrs.Name, nil) + err := rt.Apply() + + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute).NotTo(HaveKey("254-10.0.0.6/32")) + dataplane.ExpectNeighs(unix.AF_INET) + }) + It("Should skip adding an ARP entry if route is deleted via RouteRemove before sync", func() { + // Route that needs to be added + link := dataplane.AddIface(6, "cali6", true, true) + cidr := ip.MustParseCIDROrIP("10.0.0.6") + rt.SetRoutes(RouteClassLocalWorkload, link.LinkAttrs.Name, []Target{ + {CIDR: cidr, DestMAC: mac1}, + }) + rt.RouteRemove(RouteClassLocalWorkload, link.LinkAttrs.Name, cidr) + err := rt.Apply() + + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute).NotTo(HaveKey("254-10.0.0.6/32")) + dataplane.ExpectNeighs(unix.AF_INET) }) It("Should not remove routes with a source address", func() { // Route that should be left alone noopLink := dataplane.AddIface(6, "cali4", true, true) + cidr := mustParseCIDR("10.0.0.4/32") noopRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: noopLink.LinkAttrs.Index, - Dst: mustParseCIDR("10.0.0.4/32"), + Dst: cidr, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, Scope: netlink.SCOPE_LINK, Src: deviceRouteSourceAddress, Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(noopLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, noopLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.4/32"), DestMAC: mac1}, }) dataplane.AddMockRoute(&noopRoute) @@ -338,20 +408,29 @@ var _ = Describe("RouteTable", func() { Expect(err).ToNot(HaveOccurred()) Expect(dataplane.DeletedRouteKeys).ToNot(HaveKey(mocknetlink.KeyForRoute(&noopRoute))) Expect(dataplane.UpdatedRouteKeys).ToNot(HaveKey(mocknetlink.KeyForRoute(&noopRoute))) - Expect(dataplane.HasStaticArpEntry(ip.CIDRFromIPNet(noopRoute.Dst), mac1, noopLink.Attrs().Name)).To(BeTrue()) + dataplane.ExpectNeighs(unix.AF_INET, netlink.Neigh{ + Family: unix.AF_INET, + LinkIndex: noopLink.LinkAttrs.Index, + State: netlink.NUD_PERMANENT, + Type: unix.RTN_UNICAST, + IP: cidr.IP, + HardwareAddr: mac1, + }) }) It("Should update source addresses from nil to a given source", func() { // Route that needs to be updated updateLink := dataplane.AddIface(6, "cali5", true, true) + cidr := mustParseCIDR("10.0.0.5/32") updateRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: updateLink.LinkAttrs.Index, - Dst: mustParseCIDR("10.0.0.5/32"), + Dst: cidr, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, Scope: netlink.SCOPE_LINK, Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(updateLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, updateLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1}, }) dataplane.AddMockRoute(&updateRoute) @@ -363,22 +442,32 @@ var _ = Describe("RouteTable", func() { Expect(err).ToNot(HaveOccurred()) Expect(dataplane.UpdatedRouteKeys).To(HaveKey(mocknetlink.KeyForRoute(&updateRoute))) Expect(dataplane.RouteKeyToRoute[mocknetlink.KeyForRoute(&updateRoute)]).To(Equal(fixedRoute)) - Expect(dataplane.HasStaticArpEntry(ip.MustParseCIDROrIP("10.0.0.5/32"), mac1, "cali5")).To(BeTrue()) + + dataplane.ExpectNeighs(unix.AF_INET, netlink.Neigh{ + Family: unix.AF_INET, + LinkIndex: updateLink.LinkAttrs.Index, + State: netlink.NUD_PERMANENT, + Type: unix.RTN_UNICAST, + IP: cidr.IP, + HardwareAddr: mac1, + }) }) It("Should update source addresses from an old source to a new one", func() { // Route that needs to be updated updateLink := dataplane.AddIface(6, "cali5", true, true) + cidr := mustParseCIDR("10.0.0.5/32") updateRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: updateLink.LinkAttrs.Index, - Dst: mustParseCIDR("10.0.0.5/32"), + Dst: cidr, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, Scope: netlink.SCOPE_LINK, Src: net.ParseIP("192.168.0.2"), Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(updateLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, updateLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1}, }) dataplane.AddMockRoute(&updateRoute) @@ -390,7 +479,15 @@ var _ = Describe("RouteTable", func() { Expect(err).ToNot(HaveOccurred()) Expect(dataplane.UpdatedRouteKeys).To(HaveKey(mocknetlink.KeyForRoute(&updateRoute))) Expect(dataplane.RouteKeyToRoute[mocknetlink.KeyForRoute(&updateRoute)]).To(Equal(fixedRoute)) - Expect(dataplane.HasStaticArpEntry(ip.MustParseCIDROrIP("10.0.0.5/32"), mac1, "cali5")).To(BeTrue()) + + dataplane.ExpectNeighs(unix.AF_INET, netlink.Neigh{ + Family: unix.AF_INET, + LinkIndex: updateLink.LinkAttrs.Index, + State: netlink.NUD_PERMANENT, + Type: unix.RTN_UNICAST, + IP: cidr.IP, + HardwareAddr: mac1, + }) }) It("should not delete route with source address if target has the same source", func() { @@ -404,7 +501,7 @@ var _ = Describe("RouteTable", func() { Src: net.ParseIP("192.168.0.2"), Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(noopLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, noopLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1, Src: ip.FromString("192.168.0.2")}, }) dataplane.AddMockRoute(&noopRoute) @@ -425,35 +522,39 @@ var _ = Describe("RouteTable", func() { Src: net.ParseIP("192.168.0.2"), Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(noopLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, noopLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1, Src: ip.FromString("192.168.0.3")}, }) dataplane.AddMockRoute(&noopRoute) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) - Expect(dataplane.DeletedRouteKeys).To(HaveKey(mocknetlink.KeyForRoute(&noopRoute))) + routeKey := mocknetlink.KeyForRoute(&noopRoute) + Expect(dataplane.UpdatedRouteKeys).To(HaveKey(routeKey)) + Expect(dataplane.RouteKeyToRoute[routeKey].Src).To(Equal(net.ParseIP("192.168.0.3").To4())) }) }) Describe("With a device route protocol set", func() { deviceRouteProtocol := netlink.RouteProtocol(10) + ownershipPol := defaultOwnershipPolicy + ownershipPol.AllRouteProtocols = []netlink.RouteProtocol{deviceRouteProtocol} + ownershipPol.ExclusiveRouteProtocols = []netlink.RouteProtocol{deviceRouteProtocol} // Modify the route table to have the device route source address set BeforeEach(func() { - rt = NewWithShims( - []string{"^cali.*"}, + rt = New( + &ownershipPol, 4, - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, nil, deviceRouteProtocol, true, 0, logutils.NewSummarizer("test"), dataplane, + WithTimeShim(t), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }) It("Should delete routes without a protocol", func() { @@ -465,12 +566,13 @@ var _ = Describe("RouteTable", func() { It("Should add routes with a protocol", func() { // Route that needs to be added addLink := dataplane.AddIface(6, "cali6", true, true) - rt.SetRoutes(addLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, addLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.6"), DestMAC: mac1}, }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) Expect(dataplane.RouteKeyToRoute["254-10.0.0.6/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: addLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.6/32"), Type: syscall.RTN_UNICAST, @@ -478,17 +580,254 @@ var _ = Describe("RouteTable", func() { Scope: netlink.SCOPE_LINK, Table: unix.RT_TABLE_MAIN, })) + + By("Reading back the route") + Expect(rt.ReadRoutesFromKernel(addLink.LinkAttrs.Name)).To(ConsistOf( + Target{ + Type: TargetTypeLinkLocalUnicast, + CIDR: ip.MustParseCIDROrIP("10.0.0.6"), + Protocol: deviceRouteProtocol, + }), + ) + }) + It("Should add multi-path routes with interface already up", func() { + // Route that needs to be added + addLink := dataplane.AddIface(6, "cali6", true, true) + addLink2 := dataplane.AddIface(7, "cali7", true, true) + rt.SetRoutes(RouteClassLocalWorkload, InterfaceNone, []Target{ + { + Type: TargetTypeVXLAN, + CIDR: ip.MustParseCIDROrIP("10.0.0.0/24"), + MultiPath: []NextHop{ + { + IfaceName: addLink.LinkAttrs.Name, + Gw: ip.FromString("10.0.0.6"), + }, + { + IfaceName: addLink2.LinkAttrs.Name, + Gw: ip.FromString("10.0.0.7"), + }, + }, + }, + }) + err := rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, + LinkIndex: 0, + Dst: mustParseCIDR("10.0.0.0/24"), + Type: syscall.RTN_UNICAST, + Protocol: deviceRouteProtocol, + Scope: netlink.SCOPE_UNIVERSE, + Table: unix.RT_TABLE_MAIN, + Flags: syscall.RTNH_F_ONLINK, + MultiPath: []*netlink.NexthopInfo{ + { + LinkIndex: addLink.LinkAttrs.Index, + Gw: net.ParseIP("10.0.0.6").To4(), + Flags: syscall.RTNH_F_ONLINK, + }, + { + LinkIndex: addLink2.LinkAttrs.Index, + Gw: net.ParseIP("10.0.0.7").To4(), + Flags: syscall.RTNH_F_ONLINK, + }, + }, + })) + + By("Reading back the route") + Expect(rt.ReadRoutesFromKernel(InterfaceNone)).To(ConsistOf( + Target{ + Type: TargetTypeVXLAN, + CIDR: ip.MustParseCIDROrIP("10.0.0.0/24"), + Protocol: deviceRouteProtocol, + MultiPath: []NextHop{ + { + IfaceName: addLink.LinkAttrs.Name, + Gw: ip.FromString("10.0.0.6"), + }, + { + IfaceName: addLink2.LinkAttrs.Name, + Gw: ip.FromString("10.0.0.7"), + }, + }, + })) + }) + It("Should add/remove multi-path routes when interface goes up/down", func() { + // Route that needs to be added + By("Creating interfaces") + addLink := dataplane.AddIface(6, "cali6", false, false) + addLink2 := dataplane.AddIface(7, "cali7", false, false) + + By("Setting routes") + rt.SetRoutes(RouteClassLocalWorkload, InterfaceNone, []Target{ + { + Type: TargetTypeVXLAN, + CIDR: ip.MustParseCIDROrIP("10.0.0.0/24"), + MultiPath: []NextHop{ + { + IfaceName: addLink.LinkAttrs.Name, + Gw: ip.FromString("10.0.0.6"), + }, + { + IfaceName: addLink2.LinkAttrs.Name, + Gw: ip.FromString("10.0.0.7"), + }, + }, + }, + }) + + By("Apply") + err := rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(BeZero()) + + By("Bringing interfaces up") + dataplane.SetIface("cali6", true, true) + dataplane.SetIface("cali7", true, true) + rt.OnIfaceStateChanged("cali6", addLink.LinkAttrs.Index, ifacemonitor.StateUp) + rt.OnIfaceStateChanged("cali7", addLink2.LinkAttrs.Index, ifacemonitor.StateUp) + + By("Apply") + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + expectedRoute := netlink.Route{ + Family: unix.AF_INET, + LinkIndex: 0, + Dst: mustParseCIDR("10.0.0.0/24"), + Type: syscall.RTN_UNICAST, + Protocol: deviceRouteProtocol, + Scope: netlink.SCOPE_UNIVERSE, + Table: unix.RT_TABLE_MAIN, + Flags: syscall.RTNH_F_ONLINK, + MultiPath: []*netlink.NexthopInfo{ + { + LinkIndex: addLink.LinkAttrs.Index, + Gw: net.ParseIP("10.0.0.6").To4(), + Flags: syscall.RTNH_F_ONLINK, + }, + { + LinkIndex: addLink2.LinkAttrs.Index, + Gw: net.ParseIP("10.0.0.7").To4(), + Flags: syscall.RTNH_F_ONLINK, + }, + }, + } + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(Equal(expectedRoute)) + + By("Bringing one interface down") + dataplane.SetIface("cali6", false, false) + rt.OnIfaceStateChanged("cali6", addLink.LinkAttrs.Index, ifacemonitor.StateDown) + + By("Apply") + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + // It's ok to have one interface down on a multi-path route. + // Kernel keeps the route in place. + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(Equal(expectedRoute), + "Route should not be removed when only one interface is down") + + By("Bringing other interface down") + dataplane.SetIface("cali7", false, false) + rt.OnIfaceStateChanged("cali7", addLink2.LinkAttrs.Index, ifacemonitor.StateDown) + + By("Apply") + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + // The kernel will remove the route once all interfaces go down + // so we do the same to stay in sync. + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(BeZero(), + "Route should be removed when all interfaces are down") + }) + It("Should add/remove multi-path routes when interface creted/deleted", func() { + By("Setting routes") + rt.SetRoutes(RouteClassLocalWorkload, InterfaceNone, []Target{ + { + Type: TargetTypeVXLAN, + CIDR: ip.MustParseCIDROrIP("10.0.0.0/24"), + MultiPath: []NextHop{ + { + IfaceName: "cali6", + Gw: ip.FromString("10.0.0.6"), + }, + { + IfaceName: "cali7", + Gw: ip.FromString("10.0.0.7"), + }, + }, + }, + }) + + By("Apply") + err := rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(BeZero()) + + By("Creating one interface") + addLink := dataplane.AddIface(6, "cali6", false, false) + dataplane.SetIface("cali6", true, true) + rt.OnIfaceStateChanged("cali6", addLink.LinkAttrs.Index, ifacemonitor.StateUp) + + By("Apply") + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(BeZero()) + + By("Creating other interface") + addLink2 := dataplane.AddIface(7, "cali7", false, false) + dataplane.SetIface("cali7", true, true) + rt.OnIfaceStateChanged("cali7", addLink2.LinkAttrs.Index, ifacemonitor.StateUp) + + By("Apply") + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + expectedRoute := netlink.Route{ + Family: unix.AF_INET, + LinkIndex: 0, + Dst: mustParseCIDR("10.0.0.0/24"), + Type: syscall.RTN_UNICAST, + Protocol: deviceRouteProtocol, + Scope: netlink.SCOPE_UNIVERSE, + Table: unix.RT_TABLE_MAIN, + Flags: syscall.RTNH_F_ONLINK, + MultiPath: []*netlink.NexthopInfo{ + { + LinkIndex: addLink.LinkAttrs.Index, + Gw: net.ParseIP("10.0.0.6").To4(), + Flags: syscall.RTNH_F_ONLINK, + }, + { + LinkIndex: addLink2.LinkAttrs.Index, + Gw: net.ParseIP("10.0.0.7").To4(), + Flags: syscall.RTNH_F_ONLINK, + }, + }, + } + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(Equal(expectedRoute)) + + By("Deleting one interface") + dataplane.DelIface("cali6") + rt.OnIfaceStateChanged("cali6", addLink.LinkAttrs.Index, ifacemonitor.StateNotPresent) + + By("Apply") + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + // Can't have a route with a deleted interface. The ifindex becomes + // invalid. + Expect(dataplane.RouteKeyToRoute["254-10.0.0.0/24"]).To(BeZero(), + "Route should be removed when one interface deleted") }) It("Should add multiple routes with a protocol", func() { // Route that needs to be added addLink := dataplane.AddIface(6, "cali6", true, true) - rt.SetRoutes(addLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, addLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.6"), DestMAC: mac1}, {CIDR: ip.MustParseCIDROrIP("10.0.0.7"), DestMAC: mac1}, }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) Expect(dataplane.RouteKeyToRoute["254-10.0.0.6/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: addLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.6/32"), Type: syscall.RTN_UNICAST, @@ -497,6 +836,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, })) Expect(dataplane.RouteKeyToRoute["254-10.0.0.7/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: addLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.7/32"), Type: syscall.RTN_UNICAST, @@ -508,7 +848,7 @@ var _ = Describe("RouteTable", func() { It("Should add multiple routes with a protocol after persistent failures", func() { // Route that needs to be added addLink := dataplane.AddIface(6, "cali6", true, true) - rt.SetRoutes(addLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, addLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.6"), DestMAC: mac1}, {CIDR: ip.MustParseCIDROrIP("10.0.0.7"), DestMAC: mac1}, }) @@ -524,6 +864,7 @@ var _ = Describe("RouteTable", func() { err = rt.Apply() Expect(err).NotTo(HaveOccurred()) Expect(dataplane.RouteKeyToRoute["254-10.0.0.6/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: addLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.6/32"), Type: syscall.RTN_UNICAST, @@ -532,6 +873,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, })) Expect(dataplane.RouteKeyToRoute["254-10.0.0.7/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: addLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.7/32"), Type: syscall.RTN_UNICAST, @@ -544,6 +886,7 @@ var _ = Describe("RouteTable", func() { // Route that should be left alone noopLink := dataplane.AddIface(6, "cali4", true, true) noopRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: noopLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.4/32"), Type: syscall.RTN_UNICAST, @@ -551,7 +894,7 @@ var _ = Describe("RouteTable", func() { Scope: netlink.SCOPE_LINK, Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(noopLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, noopLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.4/32"), DestMAC: mac1}, }) dataplane.AddMockRoute(&noopRoute) @@ -565,13 +908,14 @@ var _ = Describe("RouteTable", func() { // Route that needs to be updated updateLink := dataplane.AddIface(6, "cali5", true, true) updateRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: updateLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.5/32"), Type: syscall.RTN_UNICAST, Scope: netlink.SCOPE_LINK, Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(updateLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, updateLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1}, }) dataplane.AddMockRoute(&updateRoute) @@ -589,6 +933,7 @@ var _ = Describe("RouteTable", func() { // Route that needs to be updated updateLink := dataplane.AddIface(6, "cali5", true, true) updateRoute := netlink.Route{ + Family: unix.AF_INET, LinkIndex: updateLink.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.5/32"), Type: syscall.RTN_UNICAST, @@ -596,7 +941,7 @@ var _ = Describe("RouteTable", func() { Scope: netlink.SCOPE_LINK, Table: unix.RT_TABLE_MAIN, } - rt.SetRoutes(updateLink.LinkAttrs.Name, []Target{ + rt.SetRoutes(RouteClassLocalWorkload, updateLink.LinkAttrs.Name, []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.5"), DestMAC: mac1}, }) dataplane.AddMockRoute(&updateRoute) @@ -622,7 +967,7 @@ var _ = Describe("RouteTable", func() { err := rt.Apply() Expect(err).ToNot(HaveOccurred()) // We try to add 10.0.0.1 back in. - rt.SetRoutes("cali1", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali1", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.1/32"), DestMAC: mac1}, }) start := time.Now() @@ -636,7 +981,7 @@ var _ = Describe("RouteTable", func() { err := rt.Apply() Expect(err).ToNot(HaveOccurred()) // We try to add 10.0.0.10, which hasn't been seen before. - rt.SetRoutes("cali1", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali1", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.10/32"), DestMAC: mac1}, }) start := time.Now() @@ -652,9 +997,7 @@ var _ = Describe("RouteTable", func() { }) It("should panic after all its retries are exhausted", func() { - for i := 0; i < 3; i++ { - Expect(rt.Apply()).To(Equal(ConnectFailed)) - } + Expect(rt.Apply()).To(Equal(ConnectFailed)) Expect(func() { _ = rt.Apply() }).To(Panic()) }) }) @@ -666,7 +1009,7 @@ var _ = Describe("RouteTable", func() { dataplane.FailuresToSimulate = mocknetlink.FailNextRouteAdd | mocknetlink.FailNextRouteReplace dataplane.PersistFailures = true - rt.RouteUpdate("cali3", Target{ + rt.RouteUpdate(RouteClassLocalWorkload, "cali3", Target{ CIDR: ip.MustParseCIDROrIP("10.20.30.40"), }) err = rt.Apply() @@ -679,6 +1022,7 @@ var _ = Describe("RouteTable", func() { It("has not programmed the route", func() { Expect(dataplane.RouteKeyToRoute).NotTo(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.20.30.40/32"), Type: syscall.RTN_UNICAST, @@ -693,6 +1037,7 @@ var _ = Describe("RouteTable", func() { Expect(err).ToNot(HaveOccurred()) Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.20.30.40/32"), Type: syscall.RTN_UNICAST, @@ -705,12 +1050,12 @@ var _ = Describe("RouteTable", func() { Describe("after adding two routes to cali3", func() { JustBeforeEach(func() { - rt.RouteUpdate("cali3", Target{ + rt.RouteUpdate(RouteClassLocalWorkload, "cali3", Target{ CIDR: ip.MustParseCIDROrIP("10.20.30.40"), }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) - rt.RouteUpdate("cali3", Target{ + rt.RouteUpdate(RouteClassLocalWorkload, "cali3", Target{ CIDR: ip.MustParseCIDROrIP("10.0.20.0/24"), }) err = rt.Apply() @@ -719,6 +1064,7 @@ var _ = Describe("RouteTable", func() { It("should have two routes for cali3", func() { Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.20.30.40/32"), Type: syscall.RTN_UNICAST, @@ -727,6 +1073,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, })) Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.0.20.0/24"), Type: syscall.RTN_UNICAST, @@ -737,12 +1084,12 @@ var _ = Describe("RouteTable", func() { }) It("should make no dataplane updates when deleting, creating and updating back to the same target before the next apply", func() { - rt.RouteRemove("cali3", ip.MustParseCIDROrIP("10.0.20.0/24")) - rt.RouteUpdate("cali3", Target{ + rt.RouteRemove(RouteClassLocalWorkload, "cali3", ip.MustParseCIDROrIP("10.0.20.0/24")) + rt.RouteUpdate(RouteClassLocalWorkload, "cali3", Target{ CIDR: ip.MustParseCIDROrIP("10.0.20.0/24"), GW: ip.FromString("1.2.3.4"), }) - rt.RouteUpdate("cali3", Target{ + rt.RouteUpdate(RouteClassLocalWorkload, "cali3", Target{ CIDR: ip.MustParseCIDROrIP("10.0.20.0/24"), }) dataplane.ResetDeltas() @@ -754,6 +1101,7 @@ var _ = Describe("RouteTable", func() { Expect(dataplane.UpdatedRouteKeys).To(BeEmpty()) Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.20.30.40/32"), Type: syscall.RTN_UNICAST, @@ -762,6 +1110,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, })) Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.0.20.0/24"), Type: syscall.RTN_UNICAST, @@ -772,8 +1121,8 @@ var _ = Describe("RouteTable", func() { }) It("should make no dataplane updates when deleting and then setting back to the same target before the next apply", func() { - rt.RouteRemove("cali3", ip.MustParseCIDROrIP("10.0.20.0/24")) - rt.SetRoutes("cali3", []Target{{ + rt.RouteRemove(RouteClassLocalWorkload, "cali3", ip.MustParseCIDROrIP("10.0.20.0/24")) + rt.SetRoutes(RouteClassLocalWorkload, "cali3", []Target{{ CIDR: ip.MustParseCIDROrIP("10.0.20.0/24"), }, { CIDR: ip.MustParseCIDROrIP("10.20.30.40"), @@ -788,6 +1137,7 @@ var _ = Describe("RouteTable", func() { Expect(dataplane.UpdatedRouteKeys).To(BeEmpty()) Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.20.30.40/32"), Type: syscall.RTN_UNICAST, @@ -796,6 +1146,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, })) Expect(dataplane.RouteKeyToRoute).To(ContainElement(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: mustParseCIDR("10.0.20.0/24"), Type: syscall.RTN_UNICAST, @@ -808,10 +1159,10 @@ var _ = Describe("RouteTable", func() { Describe("delete interface", func() { BeforeEach(func() { - rt.SetRoutes("cali1", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali1", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.1/32")}, }) - rt.SetRoutes("cali3", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali3", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.3/32")}, }) // Apply the changes. @@ -819,7 +1170,7 @@ var _ = Describe("RouteTable", func() { Expect(err).NotTo(HaveOccurred()) // Modify route and delete interface - rt.SetRoutes("cali3", nil) + rt.SetRoutes(RouteClassLocalWorkload, "cali3", nil) delete(dataplane.NameToLink, "cali3") }) It("should still get conntrack deletion invocation during resync", func() { @@ -839,61 +1190,75 @@ var _ = Describe("RouteTable", func() { // each case, we make the failure transient so that only the first Apply() should // fail. Then, at most, the second call to Apply() should succeed. for _, testFailFlags := range mocknetlink.RoutetableFailureScenarios { - failFlags := testFailFlags - desc := fmt.Sprintf("with some routes added and failures: %v", failFlags) + testFailFlags := testFailFlags + desc := fmt.Sprintf("with some routes added and failures: %v", testFailFlags) Describe(desc, func() { BeforeEach(func() { - rt.SetRoutes("cali1", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali1", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.1/32"), DestMAC: mac1}, }) - rt.SetRoutes("cali2", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali2", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.0.2/32"), DestMAC: mac2}, }) - rt.SetRoutes("cali3", []Target{ + rt.SetRoutes(RouteClassLocalWorkload, "cali3", []Target{ {CIDR: ip.MustParseCIDROrIP("10.0.1.3/32")}, }) - dataplane.FailuresToSimulate = failFlags + dataplane.FailuresToSimulate = testFailFlags }) JustBeforeEach(func() { maxTries := 1 - if failFlags != mocknetlink.FailNone { - maxTries = 2 + if testFailFlags != mocknetlink.FailNone { + maxTries = 3 } for try := 0; try < maxTries; try++ { + By("Apply") + rt.OnIfaceStateChanged("cali1", cali1.LinkAttrs.Index, ifacemonitor.StateUp) err := rt.Apply() - if err == nil { - // We should only need to retry if Apply returns an error. - log.Info("Apply returned no error, breaking out of loop") - break + if err != nil { + continue } - } - if failFlags == mocknetlink.FailNextLinkByNameNotFound { - // Special case: a "not found" error doesn't get - // rechecked straight away because it's expected - // so we have to give the RouteTable a nudge. - rt.QueueResync() - err := rt.Apply() - Expect(err).ToNot(HaveOccurred()) + if testFailFlags == mocknetlink.FailNextLinkByName || + testFailFlags == mocknetlink.FailNextLinkByNameNotFound { + // Need >1 loop to hit these cases because, on the first try, + // we go through the full resync, which doesn't use LinkByName. + continue + } + break } }) + if testFailFlags == mocknetlink.FailNextRouteAdd { + // RouteAdd is no longer used... + It("should not consume the error", func() { + // Check that all the failures we simulated were hit. + Expect(dataplane.FailuresToSimulate).To(Equal(testFailFlags), + "Error was consumed, does test need updating?") + }) + return + } It("should have consumed all failures", func() { // Check that all the failures we simulated were hit. Expect(dataplane.FailuresToSimulate).To(Equal(mocknetlink.FailNone)) }) - It("should keep correct route", func() { - Expect(dataplane.RouteKeyToRoute["254-10.0.0.1/32"]).To(Equal(netlink.Route{ - LinkIndex: cali1.LinkAttrs.Index, - Dst: &ip1, - Type: syscall.RTN_UNICAST, - Protocol: FelixRouteProtocol, - Scope: netlink.SCOPE_LINK, - Table: unix.RT_TABLE_MAIN, - })) - Expect(dataplane.AddedRouteKeys.Contains("254-10.0.0.1/32")).To(BeFalse()) - }) + // If we return "not found" then the route gets cleaned up, because conflict + // resolution determines that no routes are eligible for programming. + if testFailFlags != mocknetlink.FailNextLinkByNameNotFound { + It("should keep correct route", func() { + Expect(dataplane.RouteKeyToRoute["254-10.0.0.1/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, + LinkIndex: cali1.LinkAttrs.Index, + Dst: &ip1, + Type: syscall.RTN_UNICAST, + Protocol: FelixRouteProtocol, + Scope: netlink.SCOPE_LINK, + Table: unix.RT_TABLE_MAIN, + })) + Expect(dataplane.AddedRouteKeys.Contains("254-10.0.0.1/32")).To(BeFalse()) + }) + } It("should add new route", func() { Expect(dataplane.RouteKeyToRoute).To(HaveKey("254-10.0.0.2/32")) Expect(dataplane.RouteKeyToRoute["254-10.0.0.2/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali2.LinkAttrs.Index, Dst: &ip2, Type: syscall.RTN_UNICAST, @@ -905,6 +1270,7 @@ var _ = Describe("RouteTable", func() { It("should update changed route", func() { Expect(dataplane.RouteKeyToRoute).To(HaveKey("254-10.0.1.3/32")) Expect(dataplane.RouteKeyToRoute["254-10.0.1.3/32"]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali3.LinkAttrs.Index, Dst: &ip13, Type: syscall.RTN_UNICAST, @@ -913,7 +1279,7 @@ var _ = Describe("RouteTable", func() { Table: unix.RT_TABLE_MAIN, })) Expect(dataplane.DeletedRouteKeys.Contains("254-10.0.0.3/32")).To(BeTrue()) - Eventually(dataplane.GetDeletedConntrackEntries).Should(Equal([]net.IP{net.ParseIP("10.0.0.3").To4()})) + Eventually(dataplane.GetDeletedConntrackEntries).Should(ContainElement(net.ParseIP("10.0.0.3").To4())) }) It("should have expected number of routes at the end", func() { Expect(len(dataplane.RouteKeyToRoute)).To(Equal(4), @@ -921,14 +1287,14 @@ var _ = Describe("RouteTable", func() { len(dataplane.RouteKeyToRoute), dataplane.RouteKeyToRoute)) }) - if failFlags&(mocknetlink.FailNextSetSocketTimeout| + if testFailFlags&(mocknetlink.FailNextSetSocketTimeout| mocknetlink.FailNextSetStrict| mocknetlink.FailNextNewNetlink| mocknetlink.FailNextLinkByName| mocknetlink.FailNextLinkList| - mocknetlink.FailNextRouteAdd| + mocknetlink.FailNextRouteReplace| mocknetlink.FailNextRouteDel| - mocknetlink.FailNextAddARP| + mocknetlink.FailNextNeighSet| mocknetlink.FailNextRouteList) != 0 { It("should reconnect to netlink", func() { Expect(dataplane.NumNewNetlinkCalls).To(Equal(2)) @@ -942,6 +1308,7 @@ var _ = Describe("RouteTable", func() { Describe("after an external route addition with route removal enabled", func() { JustBeforeEach(func() { cali1Route2 = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali1.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.22/32"), Type: syscall.RTN_UNICAST, @@ -995,6 +1362,7 @@ var _ = Describe("RouteTable", func() { BeforeEach(func() { cali1 = dataplane.AddIface(2, "cali1", false, false) cali1Route = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali1.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.1/32"), Type: syscall.RTN_UNICAST, @@ -1013,51 +1381,32 @@ var _ = Describe("RouteTable", func() { mocknetlink.FailNextLinkByName, mocknetlink.FailNextRouteDel, mocknetlink.FailNextRouteList, + mocknetlink.FailNextRouteListEINTR, } { failure := failure - It(fmt.Sprintf("with a %v failure, it should give up", failure), func() { - dataplane.FailuresToSimulate = failure - err := rt.Apply() - Expect(err).To(BeNil()) - Expect(dataplane.RouteKeyToRoute).To(ConsistOf(cali1Route)) - }) - It(fmt.Sprintf("with a %v failure, it shouldn't leave the interface dirty", failure), func() { - // First Apply() with a failure. - dataplane.FailuresToSimulate = failure - err := rt.Apply() - Expect(err).ToNot(HaveOccurred()) - // All failures should have been hit. - Expect(dataplane.FailuresToSimulate).To(BeZero()) - // Try another Apply(), the interface shouldn't be marked dirty - // so nothing should happen. - err = rt.Apply() - Expect(err).ToNot(HaveOccurred()) - Expect(dataplane.RouteKeyToRoute).To(ConsistOf(cali1Route)) - }) It(fmt.Sprintf("with a %v failure it should ignore Down updates", failure), func() { // First Apply() with a failure. dataplane.FailuresToSimulate = failure - err := rt.Apply() - Expect(err).ToNot(HaveOccurred()) + _ = rt.Apply() + // Fire in the update. - rt.OnIfaceStateChanged("cali1", ifacemonitor.StateDown) + rt.OnIfaceStateChanged("cali1", 11, ifacemonitor.StateDown) // Try another Apply(), the interface shouldn't be marked dirty // so nothing should happen. - err = rt.Apply() + err := rt.Apply() Expect(err).ToNot(HaveOccurred()) - Expect(dataplane.RouteKeyToRoute).To(ConsistOf(cali1Route)) + Expect(dataplane.RouteKeyToRoute).To(BeEmpty()) }) It(fmt.Sprintf("with a %v failure, then an interface kick, it should sync", failure), func() { dataplane.FailuresToSimulate = failure - err := rt.Apply() - Expect(err).ToNot(HaveOccurred()) + _ = rt.Apply() // Set interface up - rt.OnIfaceStateChanged("cali1", ifacemonitor.StateUp) + rt.OnIfaceStateChanged("cali1", cali1.LinkAttrs.Index, ifacemonitor.StateUp) dataplane.SetIface("cali1", true, true) // Now, the apply should work. - err = rt.Apply() + err := rt.Apply() Expect(err).ToNot(HaveOccurred()) Expect(dataplane.RouteKeyToRoute).To(BeEmpty()) }) @@ -1066,14 +1415,19 @@ var _ = Describe("RouteTable", func() { Describe("with an interface that disappears", func() { BeforeEach(func() { - // Add an interface so that hte route table tries to list the routes associated with it. + // Do initial apply so that we can trigger a per-interface sync below. + err := rt.Apply() + Expect(err).NotTo(HaveOccurred()) + // Add an interface so that the route table tries to list the routes associated with it. dataplane.AddIface(2, "cali1", true, true) // But trigger the interface to disappear just before the list call. This will trigger // a list operation with no interface, resulting in an ENODEV. dataplane.DeleteInterfaceAfterLinkByName = true }) It("it should suppress the ENODEV error", func() { - rt.RouteUpdate("cali1", Target{ + // Trigger a per-interface sync. + rt.OnIfaceStateChanged("cali1", 2, ifacemonitor.StateUp) + rt.RouteUpdate(RouteClassLocalWorkload, "cali1", Target{ CIDR: ip.MustParseCIDROrIP("10.0.20.0/24"), }) err := rt.Apply() @@ -1096,14 +1450,10 @@ var _ = Describe("RouteTable (main table)", func() { // Setting an auto-increment greater than the route cleanup delay effectively // disables the grace period for these tests. t.SetAutoIncrement(11 * time.Second) - rt = NewWithShims( - []string{"^cali.*"}, + rt = New( + &defaultOwnershipPolicy, 4, - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, nil, FelixRouteProtocol, true, @@ -1111,6 +1461,9 @@ var _ = Describe("RouteTable (main table)", func() { logutils.NewSummarizer("test"), dataplane, WithRouteCleanupGracePeriod(10*time.Second), + WithTimeShim(t), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }) @@ -1125,6 +1478,7 @@ var _ = Describe("RouteTable (main table)", func() { eth0 = dataplane.AddIface(2, "eth0", true, true) cali1 = dataplane.AddIface(3, "cali1", true, true) cali1Route = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali1.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.1/32"), Type: syscall.RTN_UNICAST, @@ -1134,6 +1488,7 @@ var _ = Describe("RouteTable (main table)", func() { } dataplane.AddMockRoute(&cali1Route) cali1RouteTable100 = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali1.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.3/32"), Type: syscall.RTN_UNICAST, @@ -1143,6 +1498,7 @@ var _ = Describe("RouteTable (main table)", func() { } dataplane.AddMockRoute(&cali1RouteTable100) gatewayRoute = netlink.Route{ + Family: unix.AF_INET, LinkIndex: eth0.LinkAttrs.Index, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, @@ -1198,14 +1554,10 @@ var _ = Describe("RouteTable (table 100)", func() { // Setting an auto-increment greater than the route cleanup delay effectively // disables the grace period for these tests. t.SetAutoIncrement(11 * time.Second) - rt = NewWithShims( - []string{"^cali$", InterfaceNone}, // exact interface match + rt = New( + &ownershippol.ExclusiveOwnershipPolicy{}, 4, - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, nil, FelixRouteProtocol, true, @@ -1213,6 +1565,9 @@ var _ = Describe("RouteTable (table 100)", func() { logutils.NewSummarizer("test"), dataplane, WithRouteCleanupGracePeriod(10*time.Second), + WithTimeShim(t), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }) @@ -1227,6 +1582,7 @@ var _ = Describe("RouteTable (table 100)", func() { eth0 = dataplane.AddIface(2, "eth0", true, true) cali = dataplane.AddIface(3, "cali", true, true) caliRoute = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.1/32"), Type: syscall.RTN_UNICAST, @@ -1236,6 +1592,7 @@ var _ = Describe("RouteTable (table 100)", func() { } dataplane.AddMockRoute(&caliRoute) caliRouteTable100 = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.3/32"), Type: syscall.RTN_UNICAST, @@ -1245,6 +1602,7 @@ var _ = Describe("RouteTable (table 100)", func() { } dataplane.AddMockRoute(&caliRouteTable100) gatewayRoute = netlink.Route{ + Family: unix.AF_INET, LinkIndex: eth0.LinkAttrs.Index, Type: syscall.RTN_UNICAST, Protocol: FelixRouteProtocol, @@ -1254,6 +1612,7 @@ var _ = Describe("RouteTable (table 100)", func() { } dataplane.AddMockRoute(&gatewayRoute) throwRoute = netlink.Route{ + Family: unix.AF_INET, LinkIndex: 0, Dst: mustParseCIDR("10.10.10.10/32"), Type: syscall.RTN_THROW, @@ -1265,6 +1624,7 @@ var _ = Describe("RouteTable (table 100)", func() { // Used in tests but not added to the dataplane at the start. caliRouteTable100SameAsThrow = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali.LinkAttrs.Index, Dst: mustParseCIDR("10.10.10.10/32"), Type: syscall.RTN_UNICAST, @@ -1308,7 +1668,7 @@ var _ = Describe("RouteTable (table 100)", func() { Describe("after configuring a throw route", func() { JustBeforeEach(func() { - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassWireguard, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeThrow, }) @@ -1323,9 +1683,9 @@ var _ = Describe("RouteTable (table 100)", func() { }) }) - Describe("after configuring a throw route and then deleting and recreating the route via cali", func() { + Describe("after configuring a throw route", func() { JustBeforeEach(func() { - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassWireguard, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeThrow, }) @@ -1333,19 +1693,19 @@ var _ = Describe("RouteTable (table 100)", func() { Expect(err).ToNot(HaveOccurred()) }) - It("the throw route should be removed and the interface route added", func() { + It("should be able to toggle between throw and local iface routes", func() { // Modify the action associated with a particular destination. - for ii := 0; ii < 100; ii++ { - rt.RouteRemove(InterfaceNone, ip.MustParseCIDROrIP("10.10.10.10/32")) - rt.RouteUpdate("cali", Target{ + for ii := 0; ii < 3; ii++ { + rt.RouteRemove(RouteClassWireguard, InterfaceNone, ip.MustParseCIDROrIP("10.10.10.10/32")) + rt.RouteUpdate(RouteClassLocalWorkload, "cali", Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) Expect(dataplane.RouteKeyToRoute).To(ConsistOf(caliRoute, gatewayRoute, caliRouteTable100SameAsThrow)) - rt.RouteRemove("cali", ip.MustParseCIDROrIP("10.10.10.10/32")) - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteRemove(RouteClassLocalWorkload, "cali", ip.MustParseCIDROrIP("10.10.10.10/32")) + rt.RouteUpdate(RouteClassWireguard, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeThrow, }) @@ -1354,11 +1714,25 @@ var _ = Describe("RouteTable (table 100)", func() { Expect(dataplane.RouteKeyToRoute).To(ConsistOf(caliRoute, gatewayRoute, throwRoute)) } }) + + It("should prioritise a workload route over the throw route", func() { + rt.RouteUpdate(RouteClassLocalWorkload, "cali", Target{ + CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), + }) + err := rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute).To(ConsistOf(caliRoute, gatewayRoute, caliRouteTable100SameAsThrow)) + + rt.RouteRemove(RouteClassLocalWorkload, "cali", ip.MustParseCIDROrIP("10.10.10.10/32")) + err = rt.Apply() + Expect(err).ToNot(HaveOccurred()) + Expect(dataplane.RouteKeyToRoute).To(ConsistOf(caliRoute, gatewayRoute, throwRoute)) + }) }) Describe("throw route configured in dataplane, actual route is via cali", func() { It("the throw route should be removed and the interface route added", func() { - rt.RouteUpdate("cali", Target{ + rt.RouteUpdate(RouteClassLocalWorkload, "cali", Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), }) err := rt.Apply() @@ -1369,13 +1743,13 @@ var _ = Describe("RouteTable (table 100)", func() { Describe("after configuring an existing throw route and then deleting it", func() { JustBeforeEach(func() { - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassWireguard, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeThrow, }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) - rt.RouteRemove(InterfaceNone, ip.MustParseCIDROrIP("10.10.10.10/32")) + rt.RouteRemove(RouteClassWireguard, InterfaceNone, ip.MustParseCIDROrIP("10.10.10.10/32")) err = rt.Apply() Expect(err).ToNot(HaveOccurred()) }) @@ -1389,13 +1763,13 @@ var _ = Describe("RouteTable (table 100)", func() { Describe("after configuring a throw route and then replacing it with a blackhole route", func() { JustBeforeEach(func() { - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassIPAMBlockDrop, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeThrow, }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassIPAMBlockDrop, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeBlackhole, }) @@ -1405,6 +1779,7 @@ var _ = Describe("RouteTable (table 100)", func() { It("the blackhole route should remain", func() { Expect(dataplane.RouteKeyToRoute).To(ConsistOf(caliRoute, gatewayRoute, netlink.Route{ + Family: unix.AF_INET, LinkIndex: 0, Dst: mustParseCIDR("10.10.10.10/32"), Type: syscall.RTN_BLACKHOLE, @@ -1412,20 +1787,19 @@ var _ = Describe("RouteTable (table 100)", func() { Scope: netlink.SCOPE_UNIVERSE, Table: 100, })) - Expect(dataplane.AddedRouteKeys.Contains("100-10.10.10.10/32")).To(BeTrue()) - Expect(dataplane.DeletedRouteKeys.Contains("100-10.10.10.10/32")).To(BeTrue()) + Expect(dataplane.UpdatedRouteKeys.Contains("100-10.10.10.10/32")).To(BeTrue()) }) }) Describe("after configuring a blackhole route and then replacing it with a prohibit route", func() { JustBeforeEach(func() { - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassIPAMBlockDrop, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeBlackhole, }) err := rt.Apply() Expect(err).ToNot(HaveOccurred()) - rt.RouteUpdate(InterfaceNone, Target{ + rt.RouteUpdate(RouteClassIPAMBlockDrop, InterfaceNone, Target{ CIDR: ip.MustParseCIDROrIP("10.10.10.10/32"), Type: TargetTypeProhibit, }) @@ -1435,6 +1809,7 @@ var _ = Describe("RouteTable (table 100)", func() { It("the prohibit route should remain", func() { Expect(dataplane.RouteKeyToRoute).To(ConsistOf(caliRoute, gatewayRoute, netlink.Route{ + Family: unix.AF_INET, LinkIndex: 0, Dst: mustParseCIDR("10.10.10.10/32"), Type: syscall.RTN_PROHIBIT, @@ -1442,8 +1817,7 @@ var _ = Describe("RouteTable (table 100)", func() { Scope: netlink.SCOPE_UNIVERSE, Table: 100, })) - Expect(dataplane.AddedRouteKeys.Contains("100-10.10.10.10/32")).To(BeTrue()) - Expect(dataplane.DeletedRouteKeys.Contains("100-10.10.10.10/32")).To(BeTrue()) + Expect(dataplane.UpdatedRouteKeys.Contains("100-10.10.10.10/32")).To(BeTrue()) }) }) }) @@ -1454,6 +1828,7 @@ var _ = Describe("RouteTable (table 100)", func() { BeforeEach(func() { cali = dataplane.AddIface(2, "cali", true, true) caliRoute = netlink.Route{ + Family: unix.AF_INET, LinkIndex: cali.LinkAttrs.Index, Dst: mustParseCIDR("10.0.0.1/32"), Type: syscall.RTN_UNICAST, @@ -1465,7 +1840,7 @@ var _ = Describe("RouteTable (table 100)", func() { It("should create the table as needed", func() { // In "strict" mode, RouteListFiltered returns an error if the routing table doesn't exist. // Check that is handled and that we proceed to create the route (and thus create the routing table). - rt.RouteUpdate("cali", Target{ + rt.RouteUpdate(RouteClassLocalWorkload, "cali", Target{ CIDR: ip.MustParseCIDROrIP("10.0.0.1/32"), }) err := rt.Apply() @@ -1490,20 +1865,19 @@ var _ = Describe("Tests to verify ip version is policed", func() { Expect(func() { dataplane := mocknetlink.New() t := mocktime.New() - _ = NewWithShims( - []string{"^cali$", InterfaceNone}, + _ = New( + &defaultOwnershipPolicy, 5, // invalid IP version - dataplane.NewMockNetlink, 10*time.Second, - dataplane.AddStaticArpEntry, - dataplane, - t, nil, FelixRouteProtocol, true, 100, logutils.NewSummarizer("test"), dataplane, + WithTimeShim(t), + WithConntrackShim(dataplane), + WithNetlinkHandleShim(dataplane.NewMockNetlink), ) }).To(Panic()) }) diff --git a/felix/routetable/routeclass_string.go b/felix/routetable/routeclass_string.go new file mode 100644 index 00000000000..7a3e95e94d6 --- /dev/null +++ b/felix/routetable/routeclass_string.go @@ -0,0 +1,29 @@ +// Code generated by "stringer -type=RouteClass"; DO NOT EDIT. + +package routetable + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[RouteClassLocalWorkload-0] + _ = x[RouteClassBPFSpecial-1] + _ = x[RouteClassWireguard-2] + _ = x[RouteClassVXLANSameSubnet-3] + _ = x[RouteClassVXLANTunnel-4] + _ = x[RouteClassIPAMBlockDrop-5] + _ = x[RouteClassMax-6] +} + +const _RouteClass_name = "RouteClassLocalWorkloadRouteClassBPFSpecialRouteClassWireguardRouteClassVXLANSameSubnetRouteClassVXLANTunnelRouteClassIPAMBlockDropRouteClassMax" + +var _RouteClass_index = [...]uint8{0, 23, 43, 62, 87, 108, 131, 144} + +func (i RouteClass) String() string { + if i < 0 || i >= RouteClass(len(_RouteClass_index)-1) { + return "RouteClass(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _RouteClass_name[_RouteClass_index[i]:_RouteClass_index[i+1]] +} diff --git a/felix/routetable/routetable_suite_test.go b/felix/routetable/routetable_suite_test.go index e9c5354d007..284129b06be 100644 --- a/felix/routetable/routetable_suite_test.go +++ b/felix/routetable/routetable_suite_test.go @@ -29,7 +29,7 @@ func init() { testutils.HookLogrusForGinkgo() } -func TestRules(t *testing.T) { +func TestRouteTable(t *testing.T) { RegisterFailHandler(Fail) junitReporter := reporters.NewJUnitReporter("../report/routetable_suite.xml") RunSpecsWithDefaultAndCustomReporters(t, "RouteTable Suite", []Reporter{junitReporter}) diff --git a/felix/rules/dispatch.go b/felix/rules/dispatch.go index f9c603baf5d..34f4a70e003 100644 --- a/felix/rules/dispatch.go +++ b/felix/rules/dispatch.go @@ -389,7 +389,7 @@ func (r *DefaultRuleRenderer) endpointMarkDispatchChains( rootSetMarkRules = append(rootSetMarkRules, generictables.Rule{ Match: r.NewMatch(), Action: r.SetMaskedMark( - r.IptablesMarkNonCaliEndpoint, + r.MarkNonCaliEndpoint, epMarkMapper.GetMask(), ), Comment: []string{"Non-Cali endpoint mark"}, diff --git a/felix/rules/dispatch_test.go b/felix/rules/dispatch_test.go index 6768b29fb21..96d68852d24 100644 --- a/felix/rules/dispatch_test.go +++ b/felix/rules/dispatch_test.go @@ -33,18 +33,18 @@ var _ = Describe("Dispatch chains", func() { for _, trueOrFalse := range []bool{true, false} { kubeIPVSEnabled := trueOrFalse rrConfigNormal := Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, - WorkloadIfacePrefixes: []string{"cali", "tap"}, - KubeIPVSSupportEnabled: kubeIPVSEnabled, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, + WorkloadIfacePrefixes: []string{"cali", "tap"}, + KubeIPVSSupportEnabled: kubeIPVSEnabled, } expDropRule := generictables.Rule{ @@ -56,8 +56,8 @@ var _ = Describe("Dispatch chains", func() { smNonCaliSetMarkRule := generictables.Rule{ Match: iptables.Match(), Action: iptables.SetMaskedMarkAction{ - Mark: rrConfigNormal.IptablesMarkNonCaliEndpoint, - Mask: rrConfigNormal.IptablesMarkEndpoint, + Mark: rrConfigNormal.MarkNonCaliEndpoint, + Mask: rrConfigNormal.MarkEndpoint, }, Comment: []string{"Non-Cali endpoint mark"}, } @@ -66,7 +66,7 @@ var _ = Describe("Dispatch chains", func() { var renderer RuleRenderer BeforeEach(func() { renderer = NewRenderer(rrConfigNormal) - epMarkMapper = NewEndpointMarkMapper(rrConfigNormal.IptablesMarkEndpoint, rrConfigNormal.IptablesMarkNonCaliEndpoint) + epMarkMapper = NewEndpointMarkMapper(rrConfigNormal.MarkEndpoint, rrConfigNormal.MarkNonCaliEndpoint) }) It("should panic if interface name is empty", func() { @@ -1146,7 +1146,7 @@ func outboundGotoRule(ifaceMatch string, target string) generictables.Rule { func smUnknownEndpointDropRule(ifacePrefix string) generictables.Rule { return generictables.Rule{ - Match: iptables.Match().InInterface(ifacePrefix + "+"), + Match: iptables.Match().InInterface(ifacePrefix + iptables.Wildcard), Action: iptables.DropAction{}, Comment: []string{"Unknown endpoint"}, } diff --git a/felix/rules/endpoints.go b/felix/rules/endpoints.go index a09f06e872d..d7f31787b49 100644 --- a/felix/rules/endpoints.go +++ b/felix/rules/endpoints.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ import ( log "github.com/sirupsen/logrus" "golang.org/x/crypto/sha3" + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/felix/generictables" "github.com/projectcalico/calico/felix/hashutils" "github.com/projectcalico/calico/felix/iptables" @@ -30,16 +32,24 @@ import ( ) const ( + ingressPolicy = "ingress" + egressPolicy = "egress" alwaysAllowVXLANEncap = true alwaysAllowIPIPEncap = true ) +type TierPolicyGroups struct { + Name string + DefaultAction string + IngressPolicies []*PolicyGroup + EgressPolicies []*PolicyGroup +} + func (r *DefaultRuleRenderer) WorkloadEndpointToIptablesChains( ifaceName string, epMarkMapper EndpointMarkMapper, adminUp bool, - ingressPolicies []*PolicyGroup, - egressPolicies []*PolicyGroup, + tiers []TierPolicyGroups, profileIDs []string, ) []*generictables.Chain { allowVXLANEncapFromWorkloads := r.Config.AllowVXLANPacketsFromWorkloads @@ -48,7 +58,7 @@ func (r *DefaultRuleRenderer) WorkloadEndpointToIptablesChains( result = append(result, // Chain for traffic _to_ the endpoint. r.endpointIptablesChain( - ingressPolicies, + tiers, profileIDs, ifaceName, PolicyInboundPfx, @@ -57,6 +67,7 @@ func (r *DefaultRuleRenderer) WorkloadEndpointToIptablesChains( "", // No fail-safe chains for workloads. chainTypeNormal, adminUp, + ingressPolicy, r.filterAllowAction, // Workload endpoint chains are only used in the filter table alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, @@ -65,7 +76,7 @@ func (r *DefaultRuleRenderer) WorkloadEndpointToIptablesChains( // Encap traffic is blocked by default from workload endpoints // unless explicitly overridden. r.endpointIptablesChain( - egressPolicies, + tiers, profileIDs, ifaceName, PolicyOutboundPfx, @@ -74,6 +85,7 @@ func (r *DefaultRuleRenderer) WorkloadEndpointToIptablesChains( "", // No fail-safe chains for workloads. chainTypeNormal, adminUp, + egressPolicy, r.filterAllowAction, // Workload endpoint chains are only used in the filter table allowVXLANEncapFromWorkloads, allowIPIPEncapFromWorkloads, @@ -96,11 +108,9 @@ func (r *DefaultRuleRenderer) WorkloadEndpointToIptablesChains( func (r *DefaultRuleRenderer) HostEndpointToFilterChains( ifaceName string, + tiers []TierPolicyGroups, + forwardTiers []TierPolicyGroups, epMarkMapper EndpointMarkMapper, - ingressPolicies []*PolicyGroup, - egressPolicies []*PolicyGroup, - ingressForwardPolicies []*PolicyGroup, - egressForwardPolicies []*PolicyGroup, profileIDs []string, ) []*generictables.Chain { log.WithField("ifaceName", ifaceName).Debug("Rendering filter host endpoint chain.") @@ -108,7 +118,7 @@ func (r *DefaultRuleRenderer) HostEndpointToFilterChains( result = append(result, // Chain for output traffic _to_ the endpoint. r.endpointIptablesChain( - egressPolicies, + tiers, profileIDs, ifaceName, PolicyOutboundPfx, @@ -117,13 +127,14 @@ func (r *DefaultRuleRenderer) HostEndpointToFilterChains( ChainFailsafeOut, chainTypeNormal, true, // Host endpoints are always admin up. + egressPolicy, r.filterAllowAction, alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, ), // Chain for input traffic _from_ the endpoint. r.endpointIptablesChain( - ingressPolicies, + tiers, profileIDs, ifaceName, PolicyInboundPfx, @@ -132,13 +143,14 @@ func (r *DefaultRuleRenderer) HostEndpointToFilterChains( ChainFailsafeIn, chainTypeNormal, true, // Host endpoints are always admin up. + ingressPolicy, r.filterAllowAction, alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, ), // Chain for forward traffic _to_ the endpoint. r.endpointIptablesChain( - egressForwardPolicies, + forwardTiers, profileIDs, ifaceName, PolicyOutboundPfx, @@ -147,13 +159,14 @@ func (r *DefaultRuleRenderer) HostEndpointToFilterChains( "", // No fail-safe chains for forward traffic. chainTypeForward, true, // Host endpoints are always admin up. + egressPolicy, r.filterAllowAction, alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, ), // Chain for forward traffic _from_ the endpoint. r.endpointIptablesChain( - ingressForwardPolicies, + forwardTiers, profileIDs, ifaceName, PolicyInboundPfx, @@ -162,6 +175,7 @@ func (r *DefaultRuleRenderer) HostEndpointToFilterChains( "", // No fail-safe chains for forward traffic. chainTypeForward, true, // Host endpoints are always admin up. + ingressPolicy, r.filterAllowAction, alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, @@ -184,7 +198,7 @@ func (r *DefaultRuleRenderer) HostEndpointToFilterChains( func (r *DefaultRuleRenderer) HostEndpointToMangleEgressChains( ifaceName string, - egressPolicies []*PolicyGroup, + tiers []TierPolicyGroups, profileIDs []string, ) []*generictables.Chain { log.WithField("ifaceName", ifaceName).Debug("Render host endpoint mangle egress chain.") @@ -193,7 +207,7 @@ func (r *DefaultRuleRenderer) HostEndpointToMangleEgressChains( // ACCEPT because the mangle table is typically used, if at all, for packet // manipulations that might need to apply to our allowed traffic. r.endpointIptablesChain( - egressPolicies, + tiers, profileIDs, ifaceName, PolicyOutboundPfx, @@ -202,6 +216,7 @@ func (r *DefaultRuleRenderer) HostEndpointToMangleEgressChains( ChainFailsafeOut, chainTypeNormal, true, // Host endpoints are always admin up. + egressPolicy, r.Return(), alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, @@ -211,11 +226,11 @@ func (r *DefaultRuleRenderer) HostEndpointToMangleEgressChains( func (r *DefaultRuleRenderer) HostEndpointToRawEgressChain( ifaceName string, - egressPolicies []*PolicyGroup, + untrackedTiers []TierPolicyGroups, ) *generictables.Chain { log.WithField("ifaceName", ifaceName).Debug("Rendering raw (untracked) host endpoint egress chain.") return r.endpointIptablesChain( - egressPolicies, + untrackedTiers, nil, // We don't render profiles into the raw table. ifaceName, PolicyOutboundPfx, @@ -224,6 +239,7 @@ func (r *DefaultRuleRenderer) HostEndpointToRawEgressChain( ChainFailsafeOut, chainTypeUntracked, true, // Host endpoints are always admin up. + egressPolicy, r.Allow(), alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, @@ -232,16 +248,15 @@ func (r *DefaultRuleRenderer) HostEndpointToRawEgressChain( func (r *DefaultRuleRenderer) HostEndpointToRawChains( ifaceName string, - ingressPolicies []*PolicyGroup, - egressPolicies []*PolicyGroup, + untrackedTiers []TierPolicyGroups, ) []*generictables.Chain { - log.WithField("ifaceName", ifaceName).Debug("Rendering raw (untracked) host endpoint chain.") + log.WithField("ifaceName", ifaceName).Debugf("Rendering raw (untracked) host endpoint chain. - untrackedTiers %+v", untrackedTiers) return []*generictables.Chain{ // Chain for traffic _to_ the endpoint. - r.HostEndpointToRawEgressChain(ifaceName, egressPolicies), + r.HostEndpointToRawEgressChain(ifaceName, untrackedTiers), // Chain for traffic _from_ the endpoint. r.endpointIptablesChain( - ingressPolicies, + untrackedTiers, nil, // We don't render profiles into the raw table. ifaceName, PolicyInboundPfx, @@ -250,6 +265,7 @@ func (r *DefaultRuleRenderer) HostEndpointToRawChains( ChainFailsafeIn, chainTypeUntracked, true, // Host endpoints are always admin up. + ingressPolicy, r.Allow(), alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, @@ -259,14 +275,14 @@ func (r *DefaultRuleRenderer) HostEndpointToRawChains( func (r *DefaultRuleRenderer) HostEndpointToMangleIngressChains( ifaceName string, - preDNATPolicies []*PolicyGroup, + preDNATTiers []TierPolicyGroups, ) []*generictables.Chain { log.WithField("ifaceName", ifaceName).Debug("Rendering pre-DNAT host endpoint chain.") return []*generictables.Chain{ // Chain for traffic _from_ the endpoint. Pre-DNAT policy does not apply to // outgoing traffic through a host endpoint. r.endpointIptablesChain( - preDNATPolicies, + preDNATTiers, nil, // We don't render profiles into the raw table. ifaceName, PolicyInboundPfx, @@ -275,6 +291,7 @@ func (r *DefaultRuleRenderer) HostEndpointToMangleIngressChains( ChainFailsafeIn, chainTypePreDNAT, true, // Host endpoints are always admin up. + ingressPolicy, r.mangleAllowAction, alwaysAllowVXLANEncap, alwaysAllowIPIPEncap, @@ -326,7 +343,7 @@ func (r *DefaultRuleRenderer) PolicyGroupToIptablesChains(group *PolicyGroup) [] // is handled differently in the per-endpoint chain because we need // to continue processing in the same chain on a pass rule. rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkNotClear(r.IptablesMarkPass | r.IptablesMarkAccept), + Match: r.NewMatch().MarkNotClear(r.MarkPass | r.MarkAccept), Action: r.Return(), Comment: []string{"Return on verdict"}, }) @@ -340,12 +357,12 @@ func (r *DefaultRuleRenderer) PolicyGroupToIptablesChains(group *PolicyGroup) [] } else { // We're not the first rule in a block, only jump to this policy if // the previous policy didn't set a mark bit. - match = r.NewMatch().MarkClear(r.IptablesMarkPass | r.IptablesMarkAccept) + match = r.NewMatch().MarkClear(r.MarkPass | r.MarkAccept) } chainToJumpTo := PolicyChainName( polChainPrefix, - &proto.PolicyID{Name: polName}, + &proto.PolicyID{Tier: group.Tier, Name: polName}, ) rules = append(rules, generictables.Rule{ Match: match, @@ -358,8 +375,9 @@ func (r *DefaultRuleRenderer) PolicyGroupToIptablesChains(group *PolicyGroup) [] }} } +// endpointIptablesChain sets up iptables rules for an endpoint chain. func (r *DefaultRuleRenderer) endpointIptablesChain( - policyGroups []*PolicyGroup, + tiers []TierPolicyGroups, profileIds []string, name string, policyPrefix PolicyChainNamePrefix, @@ -368,6 +386,7 @@ func (r *DefaultRuleRenderer) endpointIptablesChain( failsafeChain string, chainType endpointChainType, adminUp bool, + policyType string, allowAction generictables.Action, allowVXLANEncap bool, allowIPIPEncap bool, @@ -408,10 +427,12 @@ func (r *DefaultRuleRenderer) endpointIptablesChain( // there's no match). rules = append(rules, generictables.Rule{ Match: r.NewMatch(), - Action: r.ClearMark(r.IptablesMarkAccept | r.IptablesMarkPass), + Action: r.ClearMark(r.MarkAccept | r.MarkPass), }) if !allowVXLANEncap { + // VXLAN encapped packets that originated in a pod should be dropped, as the encapsulation can be used to + // bypass restrictive egress policies. rules = append(rules, generictables.Rule{ Match: r.NewMatch().ProtocolNum(ProtoUDP). DestPorts(uint16(r.Config.VXLANPort)), @@ -420,6 +441,8 @@ func (r *DefaultRuleRenderer) endpointIptablesChain( }) } if !allowIPIPEncap { + // IPinIP encapped packets that originated in a pod should be dropped, as the encapsulation can be used to + // bypass restrictive egress policies. rules = append(rules, generictables.Rule{ Match: r.NewMatch().ProtocolNum(ProtoIPIP), Action: r.IptablesFilterDenyAction(), @@ -427,67 +450,86 @@ func (r *DefaultRuleRenderer) endpointIptablesChain( }) } - if len(policyGroups) > 0 { - // Then, jump to each policy (or group) in turn. - for _, polGroup := range policyGroups { - var chainsToJumpTo []string - if polGroup.ShouldBeInlined() { - // Group is too small to have its own chain. - for _, p := range polGroup.PolicyNames { - chainsToJumpTo = append(chainsToJumpTo, PolicyChainName( - policyPrefix, - &proto.PolicyID{Name: p}, - )) + for _, tier := range tiers { + var policyGroups []*PolicyGroup + if policyType == ingressPolicy { + policyGroups = tier.IngressPolicies + } else { + policyGroups = tier.EgressPolicies + } + if len(policyGroups) > 0 { + // Clear the "pass" mark. If a policy sets that mark, we'll skip the rest of the policies and + // continue processing the profiles, if there are any. + rules = append(rules, generictables.Rule{ + Match: r.NewMatch(), + Action: r.ClearMark(r.MarkPass), + Comment: []string{"Start of tier " + tier.Name}, + }) + + for _, polGroup := range policyGroups { + var chainsToJumpTo []string + if polGroup.ShouldBeInlined() { + // Group is too small to have its own chain. + for _, p := range polGroup.PolicyNames { + chainsToJumpTo = append(chainsToJumpTo, PolicyChainName( + policyPrefix, + &proto.PolicyID{Tier: tier.Name, Name: p}, + )) + } + } else { + // Group needs its own chain. + chainsToJumpTo = []string{polGroup.ChainName()} } - } else { - // Group needs its own chain. - chainsToJumpTo = []string{polGroup.ChainName()} - } + // Then, jump to each policy in turn. + for _, chainToJumpTo := range chainsToJumpTo { + // If a previous policy/group didn't set the "pass" mark, jump to the policy. + rules = append(rules, generictables.Rule{ + Match: r.NewMatch().MarkClear(r.MarkPass), + Action: r.Jump(chainToJumpTo), + }) - for _, chainToJumpTo := range chainsToJumpTo { - // If a previous policy/group didn't set the "pass" mark, jump to the policy. - rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkClear(r.IptablesMarkPass), - Action: r.Jump(chainToJumpTo), - }) - // If policy marked packet as accepted, it returns, setting the accept - // mark bit. - if chainType == chainTypeUntracked { - // For an untracked policy, map allow to "NOTRACK and ALLOW". + // If policy marked packet as accepted, it returns, setting the accept + // mark bit. + if chainType == chainTypeUntracked { + // For an untracked policy, map allow to "NOTRACK and ALLOW". + rules = append(rules, generictables.Rule{ + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), + Action: r.NoTrack(), + }) + } + // If accept bit is set, return from this chain. We don't immediately + // accept because there may be other policy still to apply. rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), - Action: r.NoTrack(), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), + Action: r.Return(), + Comment: []string{"Return if policy accepted"}, }) } - // If accept bit is set, return from this chain. We don't immediately - // accept because there may be other policy still to apply. - rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), - Action: r.Return(), - Comment: []string{"Return if policy accepted"}, - }) } - } - if chainType == chainTypeNormal || chainType == chainTypeForward { - // When rendering normal and forward rules, if no policy marked the packet as "pass", drop - // or reject the packet. - // - // For untracked and pre-DNAT rules, we don't do that because there may be - // normal rules still to be applied to the packet in the filter table. - rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkClear(r.IptablesMarkPass), - Action: r.IptablesFilterDenyAction(), - Comment: []string{fmt.Sprintf("%s if no policies passed packet", r.IptablesFilterDenyAction())}, - }) + if chainType == chainTypeNormal || chainType == chainTypeForward { + if tier.DefaultAction != string(v3.Pass) { + // When rendering normal and forward rules, if no policy marked the packet as "pass", drop the + // packet. + // + // For untracked and pre-DNAT rules, we don't do that because there may be + // normal rules still to be applied to the packet in the filter table. + rules = append(rules, generictables.Rule{ + Match: r.NewMatch().MarkClear(r.MarkPass), + Action: r.IptablesFilterDenyAction(), + Comment: []string{fmt.Sprintf("%s if no policies passed packet", r.IptablesFilterDenyAction())}, + }) + } + } } + } - } else if chainType == chainTypeForward { + if len(tiers) == 0 && chainType == chainTypeForward { // Forwarded traffic is allowed when there are no policies with // applyOnForward that apply to this endpoint (and in this direction). rules = append(rules, generictables.Rule{ Match: r.NewMatch(), - Action: r.SetMark(r.IptablesMarkAccept), + Action: r.SetMark(r.MarkAccept), Comment: []string{"Allow forwarded traffic by default"}, }) rules = append(rules, generictables.Rule{ @@ -506,7 +548,7 @@ func (r *DefaultRuleRenderer) endpointIptablesChain( // If policy marked packet as accepted, it returns, setting the // accept mark bit. If that is set, return from this chain. generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.Return(), Comment: []string{"Return if profile accepted"}, }) @@ -523,7 +565,6 @@ func (r *DefaultRuleRenderer) endpointIptablesChain( Action: r.IptablesFilterDenyAction(), Comment: []string{fmt.Sprintf("%s if no profiles matched", r.IptablesFilterDenyAction())}, }) - // } } return &generictables.Chain{ @@ -540,7 +581,7 @@ func (r *DefaultRuleRenderer) appendConntrackRules(rules []generictables.Rule, a rules = append(rules, generictables.Rule{ Match: r.NewMatch().ConntrackState("RELATED,ESTABLISHED"), - Action: r.SetMark(r.IptablesMarkAccept), + Action: r.SetMark(r.MarkAccept), }, ) } @@ -655,3 +696,20 @@ func (p PolicyGroupSliceStringer) String() string { } return "[" + strings.Join(names, ",") + "]" } + +type TierPolicyGroupsStringer []TierPolicyGroups + +func (tiers TierPolicyGroupsStringer) String() string { + if tiers == nil { + return "" + } + if len(tiers) == 0 { + return "[]" + } + parts := make([]string, len(tiers)) + for i, t := range tiers { + parts[i] = fmt.Sprintf("%s: Ingress:%s, Egress:%s", + t.Name, PolicyGroupSliceStringer(t.IngressPolicies), PolicyGroupSliceStringer(t.EgressPolicies)) + } + return "[" + strings.Join(parts, ",") + "]" +} diff --git a/felix/rules/endpoints_test.go b/felix/rules/endpoints_test.go index 8feec026f32..b389e02d796 100644 --- a/felix/rules/endpoints_test.go +++ b/felix/rules/endpoints_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import ( "fmt" "strings" + "github.com/google/go-cmp/cmp" . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" @@ -26,15 +27,17 @@ import ( "github.com/projectcalico/calico/felix/generictables" "github.com/projectcalico/calico/felix/ipsets" . "github.com/projectcalico/calico/felix/iptables" + "github.com/projectcalico/calico/felix/proto" . "github.com/projectcalico/calico/felix/rules" ) var _ = Describe("Endpoints", func() { const ( - ProtoUDP = 17 - ProtoIPIP = 4 - VXLANPort = 4789 - VXLANVNI = 4096 + ProtoUDP = 17 + ProtoIPIP = 4 + VXLANPort = 4789 + EgressIPVXLANPort = 4790 + VXLANVNI = 4096 ) for _, trueOrFalse := range []bool{true, false} { @@ -50,40 +53,40 @@ var _ = Describe("Endpoints", func() { kubeIPVSEnabled := trueOrFalse rrConfigNormalMangleReturn := Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, - KubeIPVSSupportEnabled: kubeIPVSEnabled, - IptablesMangleAllowAction: "RETURN", - IptablesFilterDenyAction: denyActionCommand, - VXLANPort: 4789, - VXLANVNI: 4096, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, + KubeIPVSSupportEnabled: kubeIPVSEnabled, + MangleAllowAction: "RETURN", + FilterDenyAction: denyActionCommand, + VXLANPort: 4789, + VXLANVNI: 4096, } rrConfigConntrackDisabledReturnAction := Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x0100, - KubeIPVSSupportEnabled: kubeIPVSEnabled, - DisableConntrackInvalid: true, - IptablesFilterAllowAction: "RETURN", - IptablesFilterDenyAction: denyActionCommand, - VXLANPort: 4789, - VXLANVNI: 4096, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, + KubeIPVSSupportEnabled: kubeIPVSEnabled, + DisableConntrackInvalid: true, + FilterAllowAction: "RETURN", + FilterDenyAction: denyActionCommand, + VXLANPort: 4789, + VXLANVNI: 4096, } var renderer RuleRenderer @@ -104,8 +107,8 @@ var _ = Describe("Endpoints", func() { Context("with normal config", func() { BeforeEach(func() { renderer = NewRenderer(rrConfigNormalMangleReturn) - epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.IptablesMarkEndpoint, - rrConfigNormalMangleReturn.IptablesMarkNonCaliEndpoint) + epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.MarkEndpoint, + rrConfigNormalMangleReturn.MarkNonCaliEndpoint) }) It("should render a minimal workload endpoint", func() { @@ -113,7 +116,6 @@ var _ = Describe("Endpoints", func() { "cali1234", epMarkMapper, true, nil, - nil, nil)).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-tw-cali1234", @@ -183,7 +185,6 @@ var _ = Describe("Endpoints", func() { false, nil, nil, - nil, )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-tw-cali1234", @@ -222,8 +223,11 @@ var _ = Describe("Endpoints", func() { "cali1234", epMarkMapper, true, - singlePolicyGroups([]string{"ai", "bi"}), - singlePolicyGroups([]string{"ae", "be"}), + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"ai", "bi"}, + EgressPolicies: []string{"ae", "be"}, + }}), []string{"prof1", "prof2"}, )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { @@ -244,9 +248,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-ai"}, + Action: JumpAction{Target: "cali-pi-default/ai"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -255,7 +264,7 @@ var _ = Describe("Endpoints", func() { }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-bi"}, + Action: JumpAction{Target: "cali-pi-default/bi"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -286,7 +295,6 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if profile accepted"}, }, - { Match: Match(), Action: denyAction, @@ -314,9 +322,14 @@ var _ = Describe("Endpoints", func() { dropVXLANRule, dropIPIPRule, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-ae"}, + Action: JumpAction{Target: "cali-po-default/ae"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -325,7 +338,7 @@ var _ = Describe("Endpoints", func() { }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-be"}, + Action: JumpAction{Target: "cali-po-default/be"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -356,7 +369,6 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if profile accepted"}, }, - { Match: Match(), Action: denyAction, @@ -408,13 +420,18 @@ var _ = Describe("Endpoints", func() { "cali1234", epMarkMapper, true, - []*PolicyGroup{ - polGrpInABC, - polGrpInEF, - }, - []*PolicyGroup{ - polGrpOutAB, - polGrpOutDE, + []TierPolicyGroups{ + { + Name: "default", + IngressPolicies: []*PolicyGroup{ + polGrpInABC, + polGrpInEF, + }, + EgressPolicies: []*PolicyGroup{ + polGrpOutAB, + polGrpOutDE, + }, + }, }, []string{"prof1", "prof2"}, )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ @@ -436,6 +453,11 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), Action: JumpAction{Target: polGrpInABC.ChainName()}, @@ -454,6 +476,7 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if policy accepted"}, }, + { Match: Match().MarkClear(0x10), Action: denyAction, @@ -478,7 +501,6 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if profile accepted"}, }, - { Match: Match(), Action: denyAction, @@ -506,6 +528,11 @@ var _ = Describe("Endpoints", func() { dropVXLANRule, dropIPIPRule, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), Action: JumpAction{Target: polGrpOutAB.ChainName()}, @@ -548,7 +575,165 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if profile accepted"}, }, + { + Match: Match(), + Action: denyAction, + Comment: []string{fmt.Sprintf("%s if no profiles matched", denyActionString)}, + }, + }, + }, + { + Name: "cali-sm-cali1234", + Rules: []generictables.Rule{ + { + Match: Match(), + Action: SetMaskedMarkAction{Mark: 0xd400, Mask: 0xff00}, + }, + }, + }, + }))) + }) + It("should render a fully-loaded workload endpoint with EndOfTierPass enabled", func() { + Expect(renderer.WorkloadEndpointToIptablesChains( + "cali1234", + epMarkMapper, + true, + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + DefaultAction: "Pass", + IngressPolicies: []string{"ai", "bi"}, + EgressPolicies: []string{"ae", "be"}, + }}), + []string{"prof1", "prof2"}, + )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ + { + Name: "cali-tw-cali1234", + Rules: []generictables.Rule{ + // conntrack rules. + { + Match: Match().ConntrackState("RELATED,ESTABLISHED"), + Action: AcceptAction{}, + }, + { + Match: Match().ConntrackState("INVALID"), + Action: denyAction, + }, + + { + Match: Match(), + Action: ClearMarkAction{Mark: 0x18}, + }, + + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, + { + Match: Match().MarkClear(0x10), + Action: JumpAction{Target: "cali-pi-default/ai"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if policy accepted"}, + }, + { + Match: Match().MarkClear(0x10), + Action: JumpAction{Target: "cali-pi-default/bi"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if policy accepted"}, + }, + { + Match: Match(), + Action: JumpAction{Target: "cali-pri-prof1"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if profile accepted"}, + }, + { + Match: Match(), + Action: JumpAction{Target: "cali-pri-prof2"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if profile accepted"}, + }, + { + Match: Match(), + Action: denyAction, + Comment: []string{fmt.Sprintf("%s if no profiles matched", denyActionString)}, + }, + }, + }, + { + Name: "cali-fw-cali1234", + Rules: []generictables.Rule{ + // conntrack rules. + { + Match: Match().ConntrackState("RELATED,ESTABLISHED"), + Action: AcceptAction{}, + }, + { + Match: Match().ConntrackState("INVALID"), + Action: denyAction, + }, + + { + Match: Match(), + Action: ClearMarkAction{Mark: 0x18}, + }, + dropVXLANRule, + dropIPIPRule, + + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, + { + Match: Match().MarkClear(0x10), + Action: JumpAction{Target: "cali-po-default/ae"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if policy accepted"}, + }, + { + Match: Match().MarkClear(0x10), + Action: JumpAction{Target: "cali-po-default/be"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if policy accepted"}, + }, + { + Match: Match(), + Action: JumpAction{Target: "cali-pro-prof1"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if profile accepted"}, + }, + { + Match: Match(), + Action: JumpAction{Target: "cali-pro-prof2"}, + }, + { + Match: Match().MarkSingleBitSet(0x8), + Action: ReturnAction{}, + Comment: []string{"Return if profile accepted"}, + }, { Match: Match(), Action: denyAction, @@ -569,11 +754,21 @@ var _ = Describe("Endpoints", func() { }) It("should render a host endpoint", func() { - Expect(renderer.HostEndpointToFilterChains("eth0", + actual := renderer.HostEndpointToFilterChains("eth0", + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"ai", "bi"}, + EgressPolicies: []string{"ae", "be"}, + }}), + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"afi", "bfi"}, + EgressPolicies: []string{"afe", "bfe"}, + }}), epMarkMapper, - singlePolicyGroups([]string{"ai", "bi"}), singlePolicyGroups([]string{"ae", "be"}), - singlePolicyGroups([]string{"afi", "bfi"}), singlePolicyGroups([]string{"afe", "bfe"}), - []string{"prof1", "prof2"})).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ + []string{"prof1", "prof2"}, + ) + expected := trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-th-eth0", Rules: []generictables.Rule{ @@ -598,9 +793,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-ae"}, + Action: JumpAction{Target: "cali-po-default/ae"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -609,7 +809,7 @@ var _ = Describe("Endpoints", func() { }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-be"}, + Action: JumpAction{Target: "cali-po-default/be"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -621,7 +821,6 @@ var _ = Describe("Endpoints", func() { Action: denyAction, Comment: []string{fmt.Sprintf("%s if no policies passed packet", denyActionString)}, }, - { Match: Match(), Action: JumpAction{Target: "cali-pro-prof1"}, @@ -640,7 +839,6 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if profile accepted"}, }, - { Match: Match(), Action: denyAction, @@ -672,9 +870,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-ai"}, + Action: JumpAction{Target: "cali-pi-default/ai"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -683,7 +886,7 @@ var _ = Describe("Endpoints", func() { }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-bi"}, + Action: JumpAction{Target: "cali-pi-default/bi"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -695,7 +898,6 @@ var _ = Describe("Endpoints", func() { Action: denyAction, Comment: []string{fmt.Sprintf("%s if no policies passed packet", denyActionString)}, }, - { Match: Match(), Action: JumpAction{Target: "cali-pri-prof1"}, @@ -714,7 +916,6 @@ var _ = Describe("Endpoints", func() { Action: ReturnAction{}, Comment: []string{"Return if profile accepted"}, }, - { Match: Match(), Action: denyAction, @@ -740,9 +941,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-afe"}, + Action: JumpAction{Target: "cali-po-default/afe"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -751,7 +957,7 @@ var _ = Describe("Endpoints", func() { }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-bfe"}, + Action: JumpAction{Target: "cali-po-default/bfe"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -783,9 +989,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Match: Match(), + Comment: []string{"Start of tier default"}, + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-afi"}, + Action: JumpAction{Target: "cali-pi-default/afi"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -794,7 +1005,7 @@ var _ = Describe("Endpoints", func() { }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-bfi"}, + Action: JumpAction{Target: "cali-pi-default/bfi"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -817,13 +1028,18 @@ var _ = Describe("Endpoints", func() { }, }, }, - }))) + }) + Expect(actual).To(Equal(expected), cmp.Diff(actual, expected)) }) It("should render host endpoint raw chains with untracked policies", func() { Expect(renderer.HostEndpointToRawChains("eth0", - singlePolicyGroups([]string{"c"}), - singlePolicyGroups([]string{"c"}))).To(Equal([]*generictables.Chain{ + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"c"}, + EgressPolicies: []string{"c"}, + }}), + )).To(Equal([]*generictables.Chain{ { Name: "cali-th-eth0", Rules: []generictables.Rule{ @@ -838,9 +1054,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Match: Match(), + Comment: []string{"Start of tier default"}, + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-po-c"}, + Action: JumpAction{Target: "cali-po-default/c"}, }, // Extra NOTRACK action before returning in raw table. { @@ -870,9 +1091,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Match: Match(), + Comment: []string{"Start of tier default"}, + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, // Extra NOTRACK action before returning in raw table. { @@ -894,7 +1120,10 @@ var _ = Describe("Endpoints", func() { It("should render host endpoint mangle chains with pre-DNAT policies", func() { Expect(renderer.HostEndpointToMangleIngressChains( "eth0", - singlePolicyGroups([]string{"c"}), + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"c"}, + }}), )).To(Equal([]*generictables.Chain{ { Name: "cali-fh-eth0", @@ -924,9 +1153,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -944,8 +1178,8 @@ var _ = Describe("Endpoints", func() { Describe("with ctstate=INVALID disabled", func() { BeforeEach(func() { renderer = NewRenderer(rrConfigConntrackDisabledReturnAction) - epMarkMapper = NewEndpointMarkMapper(rrConfigConntrackDisabledReturnAction.IptablesMarkEndpoint, - rrConfigConntrackDisabledReturnAction.IptablesMarkNonCaliEndpoint) + epMarkMapper = NewEndpointMarkMapper(rrConfigConntrackDisabledReturnAction.MarkEndpoint, + rrConfigConntrackDisabledReturnAction.MarkNonCaliEndpoint) }) It("should render a minimal workload endpoint", func() { @@ -955,7 +1189,6 @@ var _ = Describe("Endpoints", func() { true, nil, nil, - nil, )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-tw-cali1234", @@ -974,7 +1207,6 @@ var _ = Describe("Endpoints", func() { Match: Match(), Action: ClearMarkAction{Mark: 0x18}, }, - { Match: Match(), Action: denyAction, @@ -1001,7 +1233,6 @@ var _ = Describe("Endpoints", func() { }, dropVXLANRule, dropIPIPRule, - { Match: Match(), Action: denyAction, @@ -1024,7 +1255,10 @@ var _ = Describe("Endpoints", func() { It("should render host endpoint mangle chains with pre-DNAT policies", func() { Expect(renderer.HostEndpointToMangleIngressChains( "eth0", - singlePolicyGroups([]string{"c"}), + tiersToSinglePolGroups([]*proto.TierInfo{{ + Name: "default", + IngressPolicies: []string{"c"}, + }}), )).To(Equal([]*generictables.Chain{ { Name: "cali-fh-eth0", @@ -1046,9 +1280,14 @@ var _ = Describe("Endpoints", func() { Action: ClearMarkAction{Mark: 0x18}, }, + { + Comment: []string{"Start of tier default"}, + Match: Match(), + Action: ClearMarkAction{Mark: 0x10}, + }, { Match: Match().MarkClear(0x10), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, { Match: Match().MarkSingleBitSet(0x8), @@ -1062,19 +1301,19 @@ var _ = Describe("Endpoints", func() { })) }) }) + Describe("Disabling adding drop encap rules", func() { Context("VXLAN allowed, IPIP dropped", func() { It("should render a minimal workload endpoint without VXLAN drop encap rule and with IPIP drop encap rule", func() { rrConfigNormalMangleReturn.AllowVXLANPacketsFromWorkloads = true renderer = NewRenderer(rrConfigNormalMangleReturn) - epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.IptablesMarkEndpoint, - rrConfigNormalMangleReturn.IptablesMarkNonCaliEndpoint) + epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.MarkEndpoint, + rrConfigNormalMangleReturn.MarkNonCaliEndpoint) Expect(renderer.WorkloadEndpointToIptablesChains( "cali1234", epMarkMapper, true, nil, nil, - nil, )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-tw-cali1234", @@ -1088,6 +1327,7 @@ var _ = Describe("Endpoints", func() { Match: Match().ConntrackState("INVALID"), Action: denyAction, }, + { Match: Match(), Action: ClearMarkAction{Mark: 0x18}, @@ -1139,15 +1379,16 @@ var _ = Describe("Endpoints", func() { It("should render a minimal workload endpoint with VXLAN drop encap rule and without IPIP drop encap rule", func() { rrConfigNormalMangleReturn.AllowIPIPPacketsFromWorkloads = true renderer = NewRenderer(rrConfigNormalMangleReturn) - epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.IptablesMarkEndpoint, - rrConfigNormalMangleReturn.IptablesMarkNonCaliEndpoint) - Expect(renderer.WorkloadEndpointToIptablesChains( + epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.MarkEndpoint, + rrConfigNormalMangleReturn.MarkNonCaliEndpoint) + + actual := renderer.WorkloadEndpointToIptablesChains( "cali1234", epMarkMapper, true, nil, nil, - nil, - )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ + ) + expected := trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-tw-cali1234", Rules: []generictables.Rule{ @@ -1160,6 +1401,7 @@ var _ = Describe("Endpoints", func() { Match: Match().ConntrackState("INVALID"), Action: denyAction, }, + { Match: Match(), Action: ClearMarkAction{Mark: 0x18}, @@ -1204,22 +1446,23 @@ var _ = Describe("Endpoints", func() { }, }, }, - }))) + }) + Expect(actual).To(Equal(expected), cmp.Diff(actual, expected)) }) }) + Context("VXLAN and IPIP allowed", func() { It("should render a minimal workload endpoint without both VXLAN and IPIP drop encap rule", func() { rrConfigNormalMangleReturn.AllowVXLANPacketsFromWorkloads = true rrConfigNormalMangleReturn.AllowIPIPPacketsFromWorkloads = true renderer = NewRenderer(rrConfigNormalMangleReturn) - epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.IptablesMarkEndpoint, - rrConfigNormalMangleReturn.IptablesMarkNonCaliEndpoint) + epMarkMapper = NewEndpointMarkMapper(rrConfigNormalMangleReturn.MarkEndpoint, + rrConfigNormalMangleReturn.MarkNonCaliEndpoint) Expect(renderer.WorkloadEndpointToIptablesChains( "cali1234", epMarkMapper, true, nil, nil, - nil, )).To(Equal(trimSMChain(kubeIPVSEnabled, []*generictables.Chain{ { Name: "cali-tw-cali1234", @@ -1256,6 +1499,7 @@ var _ = Describe("Endpoints", func() { Match: Match().ConntrackState("INVALID"), Action: denyAction, }, + { Match: Match(), Action: ClearMarkAction{Mark: 0x18}, @@ -1299,13 +1543,27 @@ func trimSMChain(ipvsEnable bool, chains []*generictables.Chain) []*generictable return result } -func singlePolicyGroups(names []string) (groups []*PolicyGroup) { - for _, n := range names { - groups = append(groups, &PolicyGroup{ - Tier: "default", - PolicyNames: []string{n}, - }) +func tiersToSinglePolGroups(tiers []*proto.TierInfo) (tierGroups []TierPolicyGroups) { + for _, t := range tiers { + tg := TierPolicyGroups{ + Name: t.Name, + DefaultAction: t.DefaultAction, + } + for _, n := range t.IngressPolicies { + tg.IngressPolicies = append(tg.IngressPolicies, &PolicyGroup{ + Tier: t.Name, + PolicyNames: []string{n}, + }) + } + for _, n := range t.EgressPolicies { + tg.EgressPolicies = append(tg.EgressPolicies, &PolicyGroup{ + Tier: t.Name, + PolicyNames: []string{n}, + }) + } + tierGroups = append(tierGroups, tg) } + return } @@ -1382,11 +1640,12 @@ var _ = Describe("PolicyGroups", func() { var _ = table.DescribeTable("PolicyGroup chains", func(group PolicyGroup, expectedRules []generictables.Rule) { renderer := NewRenderer(Config{ - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x1, - IptablesMarkScratch1: 0x2, - IptablesMarkEndpoint: 0x4, + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x0100, }) chains := renderer.PolicyGroupToIptablesChains(&group) Expect(chains).To(HaveLen(1)) @@ -1404,7 +1663,7 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-pi-a"}, + Action: JumpAction{Target: "cali-pi-default/a"}, }, }, ), @@ -1418,11 +1677,11 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-pi-a"}, + Action: JumpAction{Target: "cali-pi-default/a"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-b"}, + Action: JumpAction{Target: "cali-pi-default/b"}, }, }, ), @@ -1436,15 +1695,15 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-pi-a"}, + Action: JumpAction{Target: "cali-pi-default/a"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-b"}, + Action: JumpAction{Target: "cali-pi-default/b"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, }, ), @@ -1458,19 +1717,19 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-pi-a"}, + Action: JumpAction{Target: "cali-pi-default/a"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-b"}, + Action: JumpAction{Target: "cali-pi-default/b"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-d"}, + Action: JumpAction{Target: "cali-pi-default/d"}, }, }, ), @@ -1484,23 +1743,23 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-pi-a"}, + Action: JumpAction{Target: "cali-pi-default/a"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-b"}, + Action: JumpAction{Target: "cali-pi-default/b"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-d"}, + Action: JumpAction{Target: "cali-pi-default/d"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-e"}, + Action: JumpAction{Target: "cali-pi-default/e"}, }, }, ), @@ -1514,23 +1773,23 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-pi-a"}, + Action: JumpAction{Target: "cali-pi-default/a"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-b"}, + Action: JumpAction{Target: "cali-pi-default/b"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-c"}, + Action: JumpAction{Target: "cali-pi-default/c"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-d"}, + Action: JumpAction{Target: "cali-pi-default/d"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-pi-e"}, + Action: JumpAction{Target: "cali-pi-default/e"}, }, { // Only get a return action every 5 rules and only if it's @@ -1541,7 +1800,7 @@ var _ = table.DescribeTable("PolicyGroup chains", }, { Match: Match(), - Action: JumpAction{Target: "cali-pi-f"}, + Action: JumpAction{Target: "cali-pi-default/f"}, }, }, ), @@ -1555,23 +1814,23 @@ var _ = table.DescribeTable("PolicyGroup chains", []generictables.Rule{ { Match: Match(), - Action: JumpAction{Target: "cali-po-a"}, + Action: JumpAction{Target: "cali-po-default/a"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-po-b"}, + Action: JumpAction{Target: "cali-po-default/b"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-po-c"}, + Action: JumpAction{Target: "cali-po-default/c"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-po-d"}, + Action: JumpAction{Target: "cali-po-default/d"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-po-e"}, + Action: JumpAction{Target: "cali-po-default/e"}, }, { Match: Match().MarkNotClear(0x18), @@ -1580,11 +1839,11 @@ var _ = table.DescribeTable("PolicyGroup chains", }, { Match: Match(), - Action: JumpAction{Target: "cali-po-f"}, + Action: JumpAction{Target: "cali-po-default/f"}, }, { Match: Match().MarkClear(0x18), - Action: JumpAction{Target: "cali-po-g"}, + Action: JumpAction{Target: "cali-po-default/g"}, }, }, ), diff --git a/felix/rules/nat_test.go b/felix/rules/nat_test.go index 69610c840cf..47f5ca15024 100644 --- a/felix/rules/nat_test.go +++ b/felix/rules/nat_test.go @@ -32,15 +32,15 @@ import ( var _ = Describe("NAT", func() { rrConfigNormal := Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x8, - IptablesMarkPass: 0x10, - IptablesMarkScratch0: 0x20, - IptablesMarkScratch1: 0x40, - IptablesMarkEndpoint: 0xff00, + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x8, + MarkPass: 0x10, + MarkScratch0: 0x20, + MarkScratch1: 0x40, + MarkEndpoint: 0xff00, } var renderer RuleRenderer diff --git a/felix/rules/policy.go b/felix/rules/policy.go index fd9c198aa55..bcd7023ccc8 100644 --- a/felix/rules/policy.go +++ b/felix/rules/policy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,11 +31,13 @@ import ( func (r *DefaultRuleRenderer) PolicyToIptablesChains(policyID *proto.PolicyID, policy *proto.Policy, ipVersion uint8) []*generictables.Chain { inbound := generictables.Chain{ - Name: PolicyChainName(PolicyInboundPfx, policyID), + Name: PolicyChainName(PolicyInboundPfx, policyID), + // Note that the policy name includes the tier, so it does not need to be separately specified. Rules: r.ProtoRulesToIptablesRules(policy.InboundRules, ipVersion, fmt.Sprintf("Policy %s ingress", policyID.Name)), } outbound := generictables.Chain{ - Name: PolicyChainName(PolicyOutboundPfx, policyID), + Name: PolicyChainName(PolicyOutboundPfx, policyID), + // Note that the policy name also includes the tier, so it does not need to be separately specified. Rules: r.ProtoRulesToIptablesRules(policy.OutboundRules, ipVersion, fmt.Sprintf("Policy %s egress", policyID.Name)), } return []*generictables.Chain{&inbound, &outbound} @@ -195,8 +197,8 @@ func (r *DefaultRuleRenderer) ProtoRuleToIptablesRules(pRule *proto.Rule, ipVers matchBlockBuilder := matchBlockBuilder{ actions: r.ActionFactory, newMatch: r.NewMatch, - markAllBlocksPass: r.IptablesMarkScratch0, - markThisBlockPass: r.IptablesMarkScratch1, + markAllBlocksPass: r.MarkScratch0, + markThisBlockPass: r.MarkScratch1, } // Port matches. We only need to render blocks of ports if, in total, there's more than one @@ -530,19 +532,19 @@ func (r *DefaultRuleRenderer) CalculateActions(pRule *proto.Rule, ipVersion uint case "", "allow": // Allow needs to set the accept mark, and then return to the calling chain for // further processing. - mark = r.IptablesMarkAccept + mark = r.MarkAccept actions = append(actions, r.Return()) case "next-tier", "pass": // pass (called next-tier in the API for historical reasons) needs to set the pass // mark, and then return to the calling chain for further processing. - mark = r.IptablesMarkPass + mark = r.MarkPass actions = append(actions, r.Return()) case "deny": // Deny maps to DROP/REJECT. actions = append(actions, r.IptablesFilterDenyAction()) case "log": // This rule should log. - actions = append(actions, r.Log(r.IptablesLogPrefix)) + actions = append(actions, r.Log(r.LogPrefix)) default: log.WithField("action", pRule.Action).Panic("Unknown rule action") } @@ -798,7 +800,7 @@ func (r *DefaultRuleRenderer) CalculateRuleMatch(pRule *proto.Rule, ipVersion ui func PolicyChainName(prefix PolicyChainNamePrefix, polID *proto.PolicyID) string { return hashutils.GetLengthLimitedID( string(prefix), - polID.Name, + polID.Tier+"/"+polID.Name, iptables.MaxChainNameLength, ) } diff --git a/felix/rules/policy_test.go b/felix/rules/policy_test.go index 83a791b0f04..d5cfa61c511 100644 --- a/felix/rules/policy_test.go +++ b/felix/rules/policy_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -186,16 +186,16 @@ var ruleTestData = []TableEntry{ var _ = Describe("Protobuf rule to iptables rule conversion", func() { rrConfigNormal := Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x80, - IptablesMarkPass: 0x100, - IptablesMarkScratch0: 0x200, - IptablesMarkScratch1: 0x400, - IptablesMarkEndpoint: 0xff000, - IptablesLogPrefix: "calico-packet", + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x80, + MarkPass: 0x100, + MarkScratch0: 0x200, + MarkScratch1: 0x400, + MarkEndpoint: 0xff000, + LogPrefix: "calico-packet", } DescribeTable( @@ -262,7 +262,7 @@ var _ = Describe("Protobuf rule to iptables rule conversion", func() { "Log rules should be correctly rendered with non-default prefix", func(ipVer int, in proto.Rule, expMatch string) { rrConfigPrefix := rrConfigNormal - rrConfigPrefix.IptablesLogPrefix = "foobar" + rrConfigPrefix.LogPrefix = "foobar" renderer := NewRenderer(rrConfigPrefix) logRule := in logRule.Action = "log" @@ -294,7 +294,7 @@ var _ = Describe("Protobuf rule to iptables rule conversion", func() { "Deny (REJECT) rules should be correctly rendered", func(ipVer int, in proto.Rule, expMatch string) { rrConfigReject := rrConfigNormal - rrConfigReject.IptablesFilterDenyAction = "REJECT" + rrConfigReject.FilterDenyAction = "REJECT" renderer := NewRenderer(rrConfigReject) denyRule := in denyRule.Action = "deny" @@ -1052,16 +1052,16 @@ var _ = Describe("rule metadata tests", func() { Protocol: &proto.Protocol{NumberOrName: &proto.Protocol_Name{Name: "tcp"}}, } rrConfigNormal := Config{ - IPIPEnabled: true, - IPIPTunnelAddress: nil, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x80, - IptablesMarkPass: 0x100, - IptablesMarkScratch0: 0x200, - IptablesMarkScratch1: 0x400, - IptablesMarkEndpoint: 0xff000, - IptablesLogPrefix: "calico-packet", + IPIPEnabled: true, + IPIPTunnelAddress: nil, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x80, + MarkPass: 0x100, + MarkScratch0: 0x200, + MarkScratch1: 0x400, + MarkEndpoint: 0xff000, + LogPrefix: "calico-packet", } It("IPv4 should include annotations in comments", func() { @@ -1095,7 +1095,7 @@ var _ = Describe("rule metadata tests", func() { ) Expect(chains).To(ConsistOf( &generictables.Chain{ - Name: "cali-pi-_ffOMcf6pikpiZ6hgKcW", + Name: "cali-pi-_FJ9yUkNpzshVDh2n7mg", Rules: []generictables.Rule{ { Match: iptables.Match(), @@ -1107,7 +1107,7 @@ var _ = Describe("rule metadata tests", func() { }, }, &generictables.Chain{ - Name: "cali-po-_ffOMcf6pikpiZ6hgKcW", + Name: "cali-po-_FJ9yUkNpzshVDh2n7mg", Rules: []generictables.Rule{ { Comment: []string{ diff --git a/felix/rules/rule_defs.go b/felix/rules/rule_defs.go index 054f40a7bf0..37bcc13a280 100644 --- a/felix/rules/rule_defs.go +++ b/felix/rules/rule_defs.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -193,7 +193,13 @@ type RuleRenderer interface { StaticFilterForwardAppendRules() []generictables.Rule WorkloadDispatchChains(map[proto.WorkloadEndpointID]*proto.WorkloadEndpoint) []*generictables.Chain - WorkloadEndpointToIptablesChains(ifaceName string, epMarkMapper EndpointMarkMapper, adminUp bool, ingressPolicies []*PolicyGroup, egressPolicies []*PolicyGroup, profileIDs []string) []*generictables.Chain + WorkloadEndpointToIptablesChains( + ifaceName string, + epMarkMapper EndpointMarkMapper, + adminUp bool, + tiers []TierPolicyGroups, + profileIDs []string, + ) []*generictables.Chain PolicyGroupToIptablesChains(group *PolicyGroup) []*generictables.Chain WorkloadInterfaceAllowChains(endpoints map[proto.WorkloadEndpointID]*proto.WorkloadEndpoint) []*generictables.Chain @@ -209,30 +215,27 @@ type RuleRenderer interface { ToHostDispatchChains(map[string]proto.HostEndpointID, string) []*generictables.Chain HostEndpointToFilterChains( ifaceName string, + tiers []TierPolicyGroups, + forwardTiers []TierPolicyGroups, epMarkMapper EndpointMarkMapper, - ingressPolicies []*PolicyGroup, - egressPolicies []*PolicyGroup, - ingressForwardPolicies []*PolicyGroup, - egressForwardPolicies []*PolicyGroup, profileIDs []string, ) []*generictables.Chain HostEndpointToMangleEgressChains( ifaceName string, - egressPolicies []*PolicyGroup, + tiers []TierPolicyGroups, profileIDs []string, ) []*generictables.Chain HostEndpointToRawEgressChain( ifaceName string, - egressPolicies []*PolicyGroup, + untrackedTiers []TierPolicyGroups, ) *generictables.Chain HostEndpointToRawChains( ifaceName string, - ingressPolicies []*PolicyGroup, - egressPolicies []*PolicyGroup, + untrackedTiers []TierPolicyGroups, ) []*generictables.Chain HostEndpointToMangleIngressChains( ifaceName string, - preDNATPolicies []*PolicyGroup, + preDNATTiers []TierPolicyGroups, ) []*generictables.Chain PolicyToIptablesChains(policyID *proto.PolicyID, policy *proto.Policy, ipVersion uint8) []*generictables.Chain @@ -294,14 +297,14 @@ type Config struct { WorkloadIfacePrefixes []string - IptablesMarkAccept uint32 - IptablesMarkPass uint32 - IptablesMarkScratch0 uint32 - IptablesMarkScratch1 uint32 - IptablesMarkEndpoint uint32 - // IptablesMarkNonCaliEndpoint is an endpoint mark which is reserved + MarkAccept uint32 + MarkPass uint32 + MarkScratch0 uint32 + MarkScratch1 uint32 + MarkEndpoint uint32 + // MarkNonCaliEndpoint is an endpoint mark which is reserved // to mark non-calico (workload or host) endpoint. - IptablesMarkNonCaliEndpoint uint32 + MarkNonCaliEndpoint uint32 KubeNodePortRanges []numorstring.Port KubeIPVSSupportEnabled bool @@ -331,17 +334,17 @@ type Config struct { WireguardEnabledV6 bool WireguardInterfaceName string WireguardInterfaceNameV6 string - WireguardIptablesMark uint32 + WireguardMark uint32 WireguardListeningPort int WireguardListeningPortV6 int WireguardEncryptHostTraffic bool RouteSource string - IptablesLogPrefix string - EndpointToHostAction string - IptablesFilterAllowAction string - IptablesMangleAllowAction string - IptablesFilterDenyAction string + LogPrefix string + EndpointToHostAction string + FilterAllowAction string + MangleAllowAction string + FilterDenyAction string FailsafeInboundHostPorts []config.ProtoPort FailsafeOutboundHostPorts []config.ProtoPort @@ -360,10 +363,10 @@ type Config struct { } var unusedBitsInBPFMode = map[string]bool{ - "IptablesMarkPass": true, - "IptablesMarkScratch1": true, - "IptablesMarkEndpoint": true, - "IptablesMarkNonCaliEndpoint": true, + "MarkPass": true, + "MarkScratch1": true, + "MarkEndpoint": true, + "MarkNonCaliEndpoint": true, } func (c *Config) validate() { @@ -375,7 +378,7 @@ func (c *Config) validate() { usedBits := uint32(0) for i := 0; i < myValue.NumField(); i++ { fieldName := myType.Field(i).Name - if strings.HasPrefix(fieldName, "IptablesMark") && fieldName != "IptablesMarkNonCaliEndpoint" { + if strings.HasPrefix(fieldName, "Mark") && fieldName != "MarkNonCaliEndpoint" { if c.BPFEnabled && unusedBitsInBPFMode[fieldName] { log.WithField("field", fieldName).Debug("Ignoring unused field in BPF mode.") continue @@ -383,11 +386,11 @@ func (c *Config) validate() { bits := myValue.Field(i).Interface().(uint32) if bits == 0 { log.WithField("field", fieldName).Panic( - "IptablesMarkXXX field not set.") + "MarkXXX field not set.") } if usedBits&bits > 0 { log.WithField("field", fieldName).Panic( - "IptablesMarkXXX field overlapped with another's bits.") + "MarkXXX field overlapped with another's bits.") } usedBits |= bits found++ @@ -395,7 +398,7 @@ func (c *Config) validate() { } if found == 0 { // Check the reflection found something we were expecting. - log.Panic("Didn't find any IptablesMarkXXX fields.") + log.Panic("Didn't find any MarkXXX fields.") } } @@ -426,7 +429,7 @@ func NewRenderer(config Config) RuleRenderer { // First, what should we do when packets are not accepted. var iptablesFilterDenyAction generictables.Action - switch config.IptablesFilterDenyAction { + switch config.FilterDenyAction { case "REJECT": log.Info("packets that are not passed by any policy or profile will be rejected.") iptablesFilterDenyAction = reject @@ -455,7 +458,7 @@ func NewRenderer(config Config) RuleRenderer { // What should we do with packets that are accepted in the forwarding chain var filterAllowAction, mangleAllowAction generictables.Action - switch config.IptablesFilterAllowAction { + switch config.FilterAllowAction { case "RETURN": log.Info("filter table allowed packets will be returned to FORWARD chain.") filterAllowAction = ret @@ -463,7 +466,7 @@ func NewRenderer(config Config) RuleRenderer { log.Info("filter table allowed packets will be accepted immediately.") filterAllowAction = accept } - switch config.IptablesMangleAllowAction { + switch config.MangleAllowAction { case "RETURN": log.Info("mangle table allowed packets will be returned to PREROUTING chain.") mangleAllowAction = ret diff --git a/felix/rules/static.go b/felix/rules/static.go index c44a66812ee..ccd632f8574 100644 --- a/felix/rules/static.go +++ b/felix/rules/static.go @@ -56,7 +56,7 @@ func (r *DefaultRuleRenderer) StaticFilterInputChains(ipVersion uint8) []*generi func (r *DefaultRuleRenderer) acceptAlreadyAccepted() []generictables.Rule { return []generictables.Rule{ { - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.filterAllowAction, }, } @@ -148,7 +148,7 @@ func (r *DefaultRuleRenderer) StaticFilterOutputForwardEndpointMarkChain() *gene // prevents the default drop at the end of the dispatch chain from dropping non-Calico // traffic. generictables.Rule{ - Match: r.NewMatch().NotMarkMatchesWithMask(r.IptablesMarkNonCaliEndpoint, r.IptablesMarkEndpoint), + Match: r.NewMatch().NotMarkMatchesWithMask(r.MarkNonCaliEndpoint, r.MarkEndpoint), Action: r.Jump(ChainDispatchFromEndPointMark), }, ) @@ -179,7 +179,7 @@ func (r *DefaultRuleRenderer) StaticFilterOutputForwardEndpointMarkChain() *gene // packet would inherit the mark bits, it would be (incorrectly) treated as a forwarded // packet. generictables.Rule{ - Action: r.ClearMark(r.IptablesMarkEndpoint), + Action: r.ClearMark(r.MarkEndpoint), }, // If a packet reaches here, one of the following must be true: @@ -194,7 +194,7 @@ func (r *DefaultRuleRenderer) StaticFilterOutputForwardEndpointMarkChain() *gene // the other case, we don't own the packet so we always return it to the OUTPUT chain // for further processing. generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.filterAllowAction, Comment: []string{"Policy explicitly accepted packet."}, }, @@ -320,13 +320,13 @@ func (r *DefaultRuleRenderer) filterInputChain(ipVersion uint8) *generictables.C // If it is, set endpoint mark and skip "to local host" rules below. inputRules = append(inputRules, generictables.Rule{ - Action: r.ClearMark(r.IptablesMarkEndpoint), + Action: r.ClearMark(r.MarkEndpoint), }, generictables.Rule{ Action: r.Jump(ChainForwardCheck), }, generictables.Rule{ - Match: r.NewMatch().MarkNotClear(r.IptablesMarkEndpoint), + Match: r.NewMatch().MarkNotClear(r.MarkEndpoint), Action: r.Return(), }, ) @@ -356,7 +356,7 @@ func (r *DefaultRuleRenderer) filterInputChain(ipVersion uint8) *generictables.C Action: r.Jump(ChainDispatchFromHostEndpoint), }, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.filterAllowAction, Comment: []string{"Host endpoint policy accepted packet."}, }, @@ -622,12 +622,12 @@ func (r *DefaultRuleRenderer) StaticFilterForwardChains() []*generictables.Chain generictables.Rule{ // we're clearing all our mark bits to minimise non-determinism caused by rules in other chains. // We exclude the accept bit because we use that to communicate from the raw/pre-dnat chains. - Action: r.ClearMark(r.allCalicoMarkBits() &^ r.IptablesMarkAccept), + Action: r.ClearMark(r.allCalicoMarkBits() &^ r.MarkAccept), }, generictables.Rule{ // Apply forward policy for the incoming Host endpoint if accept bit is clear which means the packet // was not accepted in a previous raw or pre-DNAT chain. - Match: r.NewMatch().MarkClear(r.IptablesMarkAccept), + Match: r.NewMatch().MarkClear(r.MarkAccept), Action: r.Jump(ChainDispatchFromHostEndPointForward), }, ) @@ -674,7 +674,7 @@ func (r *DefaultRuleRenderer) StaticFilterForwardChains() []*generictables.Chain func (r *DefaultRuleRenderer) StaticFilterForwardAppendRules() []generictables.Rule { return []generictables.Rule{ { - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.filterAllowAction, Comment: []string{"Policy explicitly accepted packet."}, }, @@ -682,7 +682,7 @@ func (r *DefaultRuleRenderer) StaticFilterForwardAppendRules() []generictables.R // Set IptablesMarkAccept bit here, to indicate to our mangle-POSTROUTING chain that this is // forwarded traffic and should not be subject to normal host endpoint policy. { - Action: r.SetMark(r.IptablesMarkAccept), + Action: r.SetMark(r.MarkAccept), }, } } @@ -717,7 +717,7 @@ func (r *DefaultRuleRenderer) filterOutputChain(ipVersion uint8) *generictables. // and continue execution in the parent chain (OUTPUT). rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkNotClear(r.IptablesMarkEndpoint), + Match: r.NewMatch().MarkNotClear(r.MarkEndpoint), Action: r.GoTo(ChainForwardEndpointMark), }, ) @@ -849,7 +849,7 @@ func (r *DefaultRuleRenderer) filterOutputChain(ipVersion uint8) *generictables. Action: r.Jump(ChainDispatchToHostEndpoint), }, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.filterAllowAction, Comment: []string{"Host endpoint policy accepted packet."}, }, @@ -1026,7 +1026,7 @@ func (r *DefaultRuleRenderer) StaticManglePreroutingChain(ipVersion uint8) *gene // Or if we've already accepted this packet in the raw table. rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.mangleAllowAction, }, ) @@ -1045,7 +1045,7 @@ func (r *DefaultRuleRenderer) StaticManglePreroutingChain(ipVersion uint8) *gene // In the MarkAccept case, we ACCEPT or RETURN according to // IptablesMangleAllowAction. generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.mangleAllowAction, Comment: []string{"Host endpoint policy accepted packet."}, }, @@ -1068,7 +1068,7 @@ func (r *DefaultRuleRenderer) StaticManglePostroutingChain(ipVersion uint8) *gen // any packets that reach the end of that chain. The principle is that we don't want to // apply normal host endpoint policy to forwarded traffic. rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.Return(), }) @@ -1082,7 +1082,7 @@ func (r *DefaultRuleRenderer) StaticManglePostroutingChain(ipVersion uint8) *gen if r.KubeIPVSSupportEnabled { rules = append(rules, generictables.Rule{ - Match: r.NewMatch().MarkNotClear(r.IptablesMarkEndpoint), + Match: r.NewMatch().MarkNotClear(r.MarkEndpoint), Action: r.Return(), }, ) @@ -1125,7 +1125,7 @@ func (r *DefaultRuleRenderer) StaticManglePostroutingChain(ipVersion uint8) *gen Action: r.Jump(ChainDispatchToHostEndpoint), }, generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.Return(), Comment: []string{"Host endpoint policy accepted packet."}, }, @@ -1143,7 +1143,7 @@ func (r *DefaultRuleRenderer) StaticRawTableChains(ipVersion uint8) []*genericta r.failsafeOutChain("raw", ipVersion), r.StaticRawPreroutingChain(ipVersion), r.WireguardIncomingMarkChain(), - r.StaticRawOutputChain(0), + r.StaticRawOutputChain(0, ipVersion), } } @@ -1169,15 +1169,15 @@ func (r *DefaultRuleRenderer) StaticBPFModeRawChains(ipVersion uint8, Action: r.GoTo(ChainRawBPFUntrackedPolicy), Comment: []string{"Jump to target for packets with Bypass mark"}, }, + generictables.Rule{ + Match: r.NewMatch().DestAddrType(generictables.AddrTypeLocal), + Action: r.SetMaskedMark(tcdefs.MarkSeenSkipFIB, tcdefs.MarkSeenSkipFIB), + Comment: []string{"Mark traffic towards the host - it is TRACKed"}, + }, ) if bypassHostConntrack { rawRules = append(rawRules, - generictables.Rule{ - Match: r.NewMatch().DestAddrType(generictables.AddrTypeLocal), - Action: r.SetMaskedMark(tcdefs.MarkSeenSkipFIB, tcdefs.MarkSeenSkipFIB), - Comment: []string{"Mark traffic towards the host - it is TRACKed"}, - }, generictables.Rule{ Match: r.NewMatch().NotDestAddrType(generictables.AddrTypeLocal), Action: r.GoTo(ChainRawUntrackedFlows), @@ -1270,7 +1270,7 @@ func (r *DefaultRuleRenderer) StaticBPFModeRawChains(ipVersion uint8, } chains = append(chains, - r.StaticRawOutputChain(tcdefs.MarkSeenBypass)) + r.StaticRawOutputChain(tcdefs.MarkSeenBypass, ipVersion)) return chains } @@ -1293,8 +1293,19 @@ func (r *DefaultRuleRenderer) StaticRawPreroutingChain(ipVersion uint8) *generic }) } + // Ensure VXLAN UDP Flows are not tracked in conntrack. + // VXLAN uses different source ports in each direction so + // tracking results in unreplied flows. + if (ipVersion == 4 && r.VXLANEnabled) || (ipVersion == 6 && r.VXLANEnabledV6) { + log.Debug("Adding VXLAN NOTRACK iptables rule to PREROUTING chain") + rules = append(rules, generictables.Rule{ + Match: r.NewMatch().Protocol("udp").DestPort(uint16(r.VXLANPort)), + Action: r.NoTrack(), + }) + } + // Set a mark on the packet if it's from a workload interface. - markFromWorkload := r.IptablesMarkScratch0 + markFromWorkload := r.MarkScratch0 for _, ifacePrefix := range r.WorkloadIfacePrefixes { rules = append(rules, generictables.Rule{ Match: r.NewMatch().InInterface(ifacePrefix + r.wildcard), @@ -1325,7 +1336,7 @@ func (r *DefaultRuleRenderer) StaticRawPreroutingChain(ipVersion uint8) *generic // without the mark bit set if the interface wasn't one that we're policing. We // let those packets fall through to the user's policy. generictables.Rule{ - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.Allow(), }, ) @@ -1381,10 +1392,10 @@ func (r *DefaultRuleRenderer) RPFilter(ipVersion uint8, mark, mask uint32, openS } func (r *DefaultRuleRenderer) allCalicoMarkBits() uint32 { - return r.IptablesMarkAccept | - r.IptablesMarkPass | - r.IptablesMarkScratch0 | - r.IptablesMarkScratch1 + return r.MarkAccept | + r.MarkPass | + r.MarkScratch0 | + r.MarkScratch1 } func (r *DefaultRuleRenderer) WireguardIncomingMarkChain() *generictables.Chain { @@ -1410,7 +1421,7 @@ func (r *DefaultRuleRenderer) WireguardIncomingMarkChain() *generictables.Chain }) } - rules = append(rules, generictables.Rule{Match: nil, Action: r.SetMark(r.WireguardIptablesMark)}) + rules = append(rules, generictables.Rule{Match: nil, Action: r.SetMark(r.WireguardMark)}) return &generictables.Chain{ Name: ChainSetWireguardIncomingMark, @@ -1418,7 +1429,7 @@ func (r *DefaultRuleRenderer) WireguardIncomingMarkChain() *generictables.Chain } } -func (r *DefaultRuleRenderer) StaticRawOutputChain(tcBypassMark uint32) *generictables.Chain { +func (r *DefaultRuleRenderer) StaticRawOutputChain(tcBypassMark uint32, ipVersion uint8) *generictables.Chain { rules := []generictables.Rule{ // For safety, clear all our mark bits before we start. (We could be in // append mode and another process' rules could have left the mark bit set.) @@ -1429,17 +1440,27 @@ func (r *DefaultRuleRenderer) StaticRawOutputChain(tcBypassMark uint32) *generic // return here without the mark bit set if the interface wasn't one that // we're policing. } + + // Ensure VXLAN UDP Flows are not tracked in conntrack. + if (ipVersion == 4 && r.VXLANEnabled) || (ipVersion == 6 && r.VXLANEnabledV6) { + log.Debug("Adding VXLAN NOTRACK iptables rule") + rules = append(rules, generictables.Rule{ + Match: r.NewMatch().Protocol("udp").DestPort(uint16(r.VXLANPort)), + Action: r.NoTrack(), + }) + } + if tcBypassMark == 0 { rules = append(rules, []generictables.Rule{ { - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.Allow(), }, }...) } else { rules = append(rules, []generictables.Rule{ { - Match: r.NewMatch().MarkSingleBitSet(r.IptablesMarkAccept), + Match: r.NewMatch().MarkSingleBitSet(r.MarkAccept), Action: r.SetMaskedMark(tcBypassMark, 0xffffffff), }, { diff --git a/felix/rules/static_test.go b/felix/rules/static_test.go index af4fcc42c2f..7597a6479a0 100644 --- a/felix/rules/static_test.go +++ b/felix/rules/static_test.go @@ -19,6 +19,7 @@ import ( "net" "github.com/projectcalico/calico/felix/generictables" + "github.com/projectcalico/calico/felix/iptables" . "github.com/projectcalico/calico/felix/rules" . "github.com/onsi/ginkgo" @@ -103,15 +104,15 @@ var _ = Describe("Static", func() { {Net: "0.0.0.0/0", Protocol: "tcp", Port: 23}, {Net: "0.0.0.0/0", Protocol: "tcp", Port: 1023}, }, - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x100, - KubeIPVSSupportEnabled: kubeIPVSEnabled, - KubeNodePortRanges: []numorstring.Port{{MinPort: 30030, MaxPort: 30040, PortName: ""}}, - IptablesFilterDenyAction: denyActionString, + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x100, + KubeIPVSSupportEnabled: kubeIPVSEnabled, + KubeNodePortRanges: []numorstring.Port{{MinPort: 30030, MaxPort: 30040, PortName: ""}}, + FilterDenyAction: denyActionString, } }) @@ -347,10 +348,10 @@ var _ = Describe("Static", func() { Name: "cali-INPUT", Rules: []generictables.Rule{ // Forward check chain. - {Action: ClearMarkAction{Mark: conf.IptablesMarkEndpoint}}, + {Action: ClearMarkAction{Mark: conf.MarkEndpoint}}, {Action: JumpAction{Target: ChainForwardCheck}}, { - Match: Match().MarkNotClear(conf.IptablesMarkEndpoint), + Match: Match().MarkNotClear(conf.MarkEndpoint), Action: ReturnAction{}, }, @@ -419,7 +420,7 @@ var _ = Describe("Static", func() { // From endpoint mark chain { - Match: Match().MarkNotClear(conf.IptablesMarkEndpoint), + Match: Match().MarkNotClear(conf.MarkEndpoint), Action: GotoAction{Target: ChainForwardEndpointMark}, }, @@ -691,19 +692,19 @@ var _ = Describe("Static", func() { epMark := uint32(0xff00) BeforeEach(func() { conf = Config{ - WorkloadIfacePrefixes: []string{"cali"}, - IPIPEnabled: true, - IPIPTunnelAddress: net.ParseIP("10.0.0.1"), - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: epMark, - IptablesMarkNonCaliEndpoint: 0x100, - KubeIPVSSupportEnabled: kubeIPVSEnabled, - IptablesFilterDenyAction: denyActionString, + WorkloadIfacePrefixes: []string{"cali"}, + IPIPEnabled: true, + IPIPTunnelAddress: net.ParseIP("10.0.0.1"), + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: epMark, + MarkNonCaliEndpoint: 0x100, + KubeIPVSSupportEnabled: kubeIPVSEnabled, + FilterDenyAction: denyActionString, } }) @@ -1073,6 +1074,71 @@ var _ = Describe("Static", func() { })) }) + It("IPv4: Should return expected VXLAN notrack PREROUTING chain", func() { + allCalicoMarkBits := rr.MarkAccept | + rr.MarkPass | + rr.MarkScratch0 | + rr.MarkScratch1 + markFromWorkload := rr.MarkScratch0 + + chain := &generictables.Chain{ + Name: "cali-PREROUTING", + Rules: []generictables.Rule{ + {Action: ClearMarkAction{Mark: allCalicoMarkBits}}, + { + Match: Match().Protocol("udp").DestPort(uint16(rr.VXLANPort)), + Action: NoTrackAction{}, + }, + }, + } + + for _, ifacePrefix := range rr.WorkloadIfacePrefixes { + chain.Rules = append(chain.Rules, generictables.Rule{ + Match: Match().InInterface(ifacePrefix + iptables.Wildcard), + Action: SetMarkAction{Mark: markFromWorkload}, + }) + } + + chain.Rules = append(chain.Rules, generictables.Rule{ + Match: Match().MarkMatchesWithMask(markFromWorkload, markFromWorkload), + Action: JumpAction{Target: ChainRpfSkip}, + }) + + chain.Rules = append(chain.Rules, rr.RPFilter(4, markFromWorkload, markFromWorkload, rr.OpenStackSpecialCasesEnabled, rr.IptablesFilterDenyAction())...) + chain.Rules = append(chain.Rules, generictables.Rule{ + Match: Match().MarkClear(markFromWorkload), + Action: JumpAction{Target: ChainDispatchFromHostEndpoint}, + }, generictables.Rule{ + Match: Match().MarkSingleBitSet(rr.MarkAccept), + Action: AcceptAction{}, + }) + + Expect(rr.StaticRawPreroutingChain(4)).To(Equal(chain)) + }) + + It("IPv4: Should return expected VXLAN notrack OUTPUT chain", func() { + allCalicoMarkBits := rr.MarkAccept | + rr.MarkPass | + rr.MarkScratch0 | + rr.MarkScratch1 + Expect(rr.StaticRawOutputChain(0, 4)).To(Equal(&generictables.Chain{ + Name: "cali-OUTPUT", + Rules: []generictables.Rule{ + {Action: ClearMarkAction{Mark: allCalicoMarkBits}}, + {Action: JumpAction{Target: ChainDispatchToHostEndpoint}}, + { + Match: Match().Protocol("udp").DestPort(uint16(rr.VXLANPort)), + Action: NoTrackAction{}, + }, + { + Match: Match().MarkSingleBitSet(rr.MarkAccept), + Action: AcceptAction{}, + }, + }, + }, + )) + }) + Describe("and IPv4 tunnel IP", func() { BeforeEach(func() { conf.VXLANTunnelAddress = net.IP{10, 0, 0, 1} @@ -1125,6 +1191,48 @@ var _ = Describe("Static", func() { })) }) + It("IPv6: Should return expected VXLAN notrack PREROUTING chain", func() { + allCalicoMarkBits := rr.MarkAccept | + rr.MarkPass | + rr.MarkScratch0 | + rr.MarkScratch1 + markFromWorkload := rr.MarkScratch0 + + chain := &generictables.Chain{ + Name: "cali-PREROUTING", + Rules: []generictables.Rule{ + {Action: ClearMarkAction{Mark: allCalicoMarkBits}}, + { + Match: Match().Protocol("udp").DestPort(uint16(rr.VXLANPort)), + Action: NoTrackAction{}, + }, + }, + } + + for _, ifacePrefix := range rr.WorkloadIfacePrefixes { + chain.Rules = append(chain.Rules, generictables.Rule{ + Match: Match().InInterface(ifacePrefix + iptables.Wildcard), + Action: SetMarkAction{Mark: markFromWorkload}, + }) + } + + chain.Rules = append(chain.Rules, generictables.Rule{ + Match: Match().MarkMatchesWithMask(markFromWorkload, markFromWorkload), + Action: JumpAction{Target: ChainRpfSkip}, + }) + + chain.Rules = append(chain.Rules, rr.RPFilter(6, markFromWorkload, markFromWorkload, rr.OpenStackSpecialCasesEnabled, rr.IptablesFilterDenyAction())...) + chain.Rules = append(chain.Rules, generictables.Rule{ + Match: Match().MarkClear(markFromWorkload), + Action: JumpAction{Target: ChainDispatchFromHostEndpoint}, + }, generictables.Rule{ + Match: Match().MarkSingleBitSet(rr.MarkAccept), + Action: AcceptAction{}, + }) + + Expect(rr.StaticRawPreroutingChain(6)).To(Equal(chain)) + }) + Describe("and IPv6 tunnel IP", func() { BeforeEach(func() { conf.VXLANTunnelAddressV6 = net.ParseIP("dead:beef::1") @@ -1168,16 +1276,16 @@ var _ = Describe("Static", func() { Describe("with multiple KubePortRanges", func() { BeforeEach(func() { conf = Config{ - WorkloadIfacePrefixes: []string{"cali"}, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x100, - KubeIPVSSupportEnabled: true, + WorkloadIfacePrefixes: []string{"cali"}, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x100, + KubeIPVSSupportEnabled: true, KubeNodePortRanges: []numorstring.Port{ {MinPort: 30030, MaxPort: 30040, PortName: ""}, {MinPort: 30130, MaxPort: 30140, PortName: ""}, @@ -1269,12 +1377,12 @@ var _ = Describe("Static", func() { OpenStackSpecialCasesEnabled: true, OpenStackMetadataIP: net.ParseIP("10.0.0.1"), OpenStackMetadataPort: 1234, - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x100, + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x100, } }) @@ -1384,13 +1492,13 @@ var _ = Describe("Static", func() { OpenStackSpecialCasesEnabled: true, OpenStackMetadataIP: net.ParseIP("10.0.0.1"), OpenStackMetadataPort: 1234, - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x100, - IptablesFilterAllowAction: "RETURN", + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x100, + FilterAllowAction: "RETURN", } }) @@ -1462,17 +1570,17 @@ var _ = Describe("Static", func() { epMark := uint32(0xff00) BeforeEach(func() { conf = Config{ - WorkloadIfacePrefixes: []string{"cali"}, - IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), - IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: epMark, - IptablesMarkNonCaliEndpoint: 0x100, - IptablesFilterAllowAction: "RETURN", - IptablesMangleAllowAction: "RETURN", + WorkloadIfacePrefixes: []string{"cali"}, + IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), + IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: epMark, + MarkNonCaliEndpoint: 0x100, + FilterAllowAction: "RETURN", + MangleAllowAction: "RETURN", } }) @@ -1584,17 +1692,17 @@ var _ = Describe("Static", func() { WorkloadIfacePrefixes: []string{"cali"}, IPSetConfigV4: ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil), IPSetConfigV6: ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil), - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - IptablesMarkScratch1: 0x80, - IptablesMarkEndpoint: 0xff00, - IptablesMarkNonCaliEndpoint: 0x100, + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + MarkScratch1: 0x80, + MarkEndpoint: 0xff00, + MarkNonCaliEndpoint: 0x100, WireguardEnabled: enableIPv4, WireguardEnabledV6: enableIPv6, WireguardInterfaceName: "wireguard.cali", WireguardInterfaceNameV6: "wg-v6.cali", - WireguardIptablesMark: 0x100000, + WireguardMark: 0x100000, WireguardListeningPort: 51820, WireguardListeningPortV6: 51821, WireguardEncryptHostTraffic: true, @@ -1753,10 +1861,10 @@ var _ = Describe("Static", func() { BeforeEach(func() { conf = Config{ - IptablesMarkAccept: 0x10, - IptablesMarkPass: 0x20, - IptablesMarkScratch0: 0x40, - BPFEnabled: true, + MarkAccept: 0x10, + MarkPass: 0x20, + MarkScratch0: 0x40, + BPFEnabled: true, } }) diff --git a/felix/vxlanfdb/vxlan_fdb.go b/felix/vxlanfdb/vxlan_fdb.go index f1f15f25f2d..49219dcdb54 100644 --- a/felix/vxlanfdb/vxlan_fdb.go +++ b/felix/vxlanfdb/vxlan_fdb.go @@ -17,6 +17,7 @@ package vxlanfdb import ( "fmt" "net" + "slices" "time" "github.com/pkg/errors" @@ -111,9 +112,13 @@ func New( log.WithField("family", family).Panic("Unknown family") } f := VXLANFDB{ - family: family, - ifaceName: ifaceName, - arpEntries: deltatracker.New[string, ipMACMapping](), + family: family, + ifaceName: ifaceName, + arpEntries: deltatracker.New[string, ipMACMapping]( + deltatracker.WithValuesEqualFn[string, ipMACMapping](func(a, b ipMACMapping) bool { + return a.IP == b.IP && slices.Equal(a.MAC, b.MAC) + }), + ), fdbEntries: deltatracker.New[string, ipMACMapping](), logCxt: log.WithFields(log.Fields{ "iface": ifaceName, diff --git a/felix/wireguard/wireguard.go b/felix/wireguard/wireguard.go index a7185c82b4f..7312ceb673c 100644 --- a/felix/wireguard/wireguard.go +++ b/felix/wireguard/wireguard.go @@ -34,6 +34,7 @@ import ( "github.com/projectcalico/calico/felix/netlinkshim" "github.com/projectcalico/calico/felix/routerule" "github.com/projectcalico/calico/felix/routetable" + "github.com/projectcalico/calico/felix/routetable/ownershippol" "github.com/projectcalico/calico/felix/timeshim" lclogutils "github.com/projectcalico/calico/libcalico-go/lib/logutils" "github.com/projectcalico/calico/libcalico-go/lib/set" @@ -64,10 +65,6 @@ var ( zeroKey = wgtypes.Key{} ) -type noOpConnTrack struct{} - -func (*noOpConnTrack) RemoveConntrackFlows(ipVersion uint8, ipAddr net.IP) {} - type nodeData struct { endpointAddr ip.Addr publicKey wgtypes.Key @@ -157,7 +154,7 @@ type Wireguard struct { publicKeyToNodeNames map[wgtypes.Key]set.Set[string] // Wireguard routing table and rule managers - routetable routetable.RouteTableInterface + routetable *routetable.ClassView routerule *routerule.RouteRules // Callback function used to notify of public key updates for the local nodeData @@ -226,23 +223,36 @@ func NewWithShims( } // Create routetable. We provide dummy callbacks for ARP and conntrack processing. - var rt routetable.RouteTableInterface + var rt routetable.Interface if !config.RouteSyncDisabled { - logCtx.Debug("RouteSyncDisabled is false.") - rt = routetable.NewWithShims( - []string{"^" + interfaceName + "$", routetable.InterfaceNone}, + logCtx.Debug("Route sync is enabled.") + rt = routetable.New( + // All the routes in this table belong to us, but we filter on + // interface name to optimise RouteTable's occupancy. + &ownershippol.ExclusiveOwnershipPolicy{ + InterfaceNames: []string{ + interfaceName, + routetable.InterfaceNone, + }, + }, ipVersion, - newRoutetableNetlink, netlinkTimeout, - func(cidr ip.CIDR, destMAC net.HardwareAddr, ifaceName string) error { return nil }, // addStaticARPEntry - &noOpConnTrack{}, - timeShim, nil, // deviceRouteSourceAddress deviceRouteProtocol, true, // removeExternalRoutes config.RoutingTableIndex, opRecorder, featureDetector, + // Note: deliberately not including: + // - Static neighbor entries: wireguard devices are L3. + // - Grace period: wireguard routes should be cleaned up immediately. + + // Wireguard works as an alternative higher-priority route to the + // same destination, so we don't want to delete conntrack entries + // when moving a route to the wiregaurd interface. + routetable.WithConntrackCleanup(false), + routetable.WithTimeShim(timeShim), + routetable.WithNetlinkHandleShim(newRoutetableNetlink), ) } else { logCtx.Info("RouteSyncDisabled is true, using DummyTable.") @@ -279,7 +289,7 @@ func NewWithShims( cidrToNodeName: map[ip.CIDR]string{}, publicKeyToNodeNames: map[wgtypes.Key]set.Set[string]{}, nodeUpdates: map[string]*nodeUpdateData{}, - routetable: rt, + routetable: routetable.NewClassView(routetable.RouteClassWireguard, rt), routerule: rr, statusCallback: statusCallback, localIPs: set.New[ip.Addr](), @@ -291,7 +301,7 @@ func NewWithShims( } } -func (w *Wireguard) OnIfaceStateChanged(ifaceName string, state ifacemonitor.State) { +func (w *Wireguard) OnIfaceStateChanged(ifaceName string, ifIndex int, state ifacemonitor.State) { logCtx := w.logCtx.WithField("wireguardIfaceName", w.interfaceName) if w.interfaceName != ifaceName { logCtx.WithField("ifaceName", ifaceName).Debug("Ignoring interface state change, not the wireguard interface.") @@ -310,7 +320,7 @@ func (w *Wireguard) OnIfaceStateChanged(ifaceName string, state ifacemonitor.Sta } // Notify the wireguard routetable module. - w.routetable.OnIfaceStateChanged(ifaceName, state) + w.routetable.OnIfaceStateChanged(ifaceName, ifIndex, state) } // EndpointUpdate is called when a wireguard endpoint (a node) is updated. This controls which peers to configure. diff --git a/felix/wireguard/wireguard_test.go b/felix/wireguard/wireguard_test.go index 43ff76091e7..b01c50d93e5 100644 --- a/felix/wireguard/wireguard_test.go +++ b/felix/wireguard/wireguard_test.go @@ -15,6 +15,8 @@ package wireguard_test import ( + "golang.org/x/sys/unix" + "github.com/projectcalico/calico/felix/environment" "github.com/projectcalico/calico/felix/logutils" . "github.com/projectcalico/calico/felix/wireguard" @@ -384,7 +386,7 @@ func describeEnableTests(enableV4, enableV6 bool) { // Iface update indicating down. if enableV4 { wgDataplane.ResetDeltas() - wg.OnIfaceStateChanged(ifaceName, ifacemonitor.StateDown) + wg.OnIfaceStateChanged(ifaceName, 101, ifacemonitor.StateDown) err := wg.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgDataplane.NumLinkAddCalls).To(Equal(0)) @@ -392,7 +394,7 @@ func describeEnableTests(enableV4, enableV6 bool) { } if enableV6 { wgDataplaneV6.ResetDeltas() - wgV6.OnIfaceStateChanged(ifaceNameV6, ifacemonitor.StateDown) + wgV6.OnIfaceStateChanged(ifaceNameV6, 101, ifacemonitor.StateDown) err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgDataplaneV6.NumLinkAddCalls).To(Equal(0)) @@ -405,7 +407,7 @@ func describeEnableTests(enableV4, enableV6 bool) { if enableV4 { wgDataplane.ResetDeltas() wgDataplane.AddIface(1919, ifaceName+".foobar", true, true) - wg.OnIfaceStateChanged(ifaceName+".foobar", ifacemonitor.StateUp) + wg.OnIfaceStateChanged(ifaceName+".foobar", 1919, ifacemonitor.StateUp) err := wg.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgDataplane.NumLinkAddCalls).To(Equal(0)) @@ -414,7 +416,7 @@ func describeEnableTests(enableV4, enableV6 bool) { if enableV6 { wgDataplaneV6.ResetDeltas() wgDataplaneV6.AddIface(1919, ifaceNameV6+".foobar", true, true) - wgV6.OnIfaceStateChanged(ifaceNameV6+".foobar", ifacemonitor.StateUp) + wgV6.OnIfaceStateChanged(ifaceNameV6+".foobar", 1919, ifacemonitor.StateUp) err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgDataplaneV6.NumLinkAddCalls).To(Equal(0)) @@ -425,7 +427,7 @@ func describeEnableTests(enableV4, enableV6 bool) { It("should handle status update raising an error", func() { if enableV4 { wgDataplane.SetIface(ifaceName, true, true) - wg.OnIfaceStateChanged(ifaceName, ifacemonitor.StateUp) + wg.OnIfaceStateChanged(ifaceName, 101, ifacemonitor.StateUp) s.statusErr = errors.New("foobarbaz") err := wg.Apply() Expect(err).To(HaveOccurred()) @@ -433,7 +435,7 @@ func describeEnableTests(enableV4, enableV6 bool) { } if enableV6 { wgDataplaneV6.SetIface(ifaceNameV6, true, true) - wgV6.OnIfaceStateChanged(ifaceNameV6, ifacemonitor.StateUp) + wgV6.OnIfaceStateChanged(ifaceNameV6, 101, ifacemonitor.StateUp) sV6.statusErr = errors.New("foobarbaz") err := wgV6.Apply() Expect(err).To(HaveOccurred()) @@ -445,13 +447,15 @@ func describeEnableTests(enableV4, enableV6 bool) { BeforeEach(func() { if enableV4 { wgDataplane.SetIface(ifaceName, true, true) - wg.OnIfaceStateChanged(ifaceName, ifacemonitor.StateUp) + rtDataplane.AddIface(101, ifaceName, true, true) + wg.OnIfaceStateChanged(ifaceName, 101, ifacemonitor.StateUp) err := wg.Apply() Expect(err).NotTo(HaveOccurred()) } if enableV6 { wgDataplaneV6.SetIface(ifaceNameV6, true, true) - wgV6.OnIfaceStateChanged(ifaceNameV6, ifacemonitor.StateUp) + rtDataplaneV6.AddIface(101, ifaceNameV6, true, true) + wgV6.OnIfaceStateChanged(ifaceNameV6, 101, ifacemonitor.StateUp) err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) } @@ -1125,10 +1129,9 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wg.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_6)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_6)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_6)) } if enableV6 { wgDataplaneV6.ResetDeltas() @@ -1139,10 +1142,9 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_6)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_6)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_6)) } }) @@ -1155,10 +1157,9 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wg.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_6)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_6)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_6)) } if enableV6 { wgDataplaneV6.ResetDeltas() @@ -1168,10 +1169,9 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_6)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_6)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_6)) } }) @@ -1186,10 +1186,9 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wg.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_6)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_6)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_6)) } if enableV6 { wgDataplaneV6.ResetDeltas() @@ -1201,10 +1200,9 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_6)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_6)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_6)) } }) }) @@ -1468,6 +1466,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_4)) Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_4)) Expect(rtDataplane.RouteKeyToRoute[routekey_1]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: link.LinkAttrs.Index, Dst: &ipnet_1, Type: syscall.RTN_UNICAST, @@ -1476,6 +1475,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Table: tableIndex, })) Expect(rtDataplane.RouteKeyToRoute[routekey_2]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: link.LinkAttrs.Index, Dst: &ipnet_2, Type: syscall.RTN_UNICAST, @@ -1484,6 +1484,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Table: tableIndex, })) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: link.LinkAttrs.Index, Dst: &ipnet_3, Type: syscall.RTN_UNICAST, @@ -1492,6 +1493,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Table: tableIndex, })) Expect(rtDataplane.RouteKeyToRoute[routekey_4]).To(Equal(netlink.Route{ + Family: unix.AF_INET, Dst: &ipnet_4, Type: syscall.RTN_THROW, Protocol: FelixRouteProtocol, @@ -1507,6 +1509,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_4)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_1]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: linkV6.LinkAttrs.Index, Dst: &ipnetV6_1, Type: syscall.RTN_UNICAST, @@ -1515,6 +1518,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Table: tableIndex, })) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_2]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: linkV6.LinkAttrs.Index, Dst: &ipnetV6_2, Type: syscall.RTN_UNICAST, @@ -1523,6 +1527,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Table: tableIndex, })) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: linkV6.LinkAttrs.Index, Dst: &ipnetV6_3, Type: syscall.RTN_UNICAST, @@ -1531,6 +1536,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Table: tableIndex, })) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_4]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: 1, Dst: &ipnetV6_4, Type: syscall.RTN_THROW, @@ -1713,15 +1719,15 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wg.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wg.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_3)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplane.WireguardConfigUpdated).To(BeTrue()) Expect(link.WireguardPeers).To(HaveLen(1)) Expect(link.WireguardPeers).To(HaveLen(1)) Expect(link.WireguardPeers).To(HaveKey(key_peer1)) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, Dst: &ipnet_3, Type: syscall.RTN_THROW, Protocol: FelixRouteProtocol, @@ -1768,15 +1774,15 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgV6.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplaneV6.WireguardConfigUpdated).To(BeTrue()) Expect(linkV6.WireguardPeers).To(HaveLen(1)) Expect(linkV6.WireguardPeers).To(HaveLen(1)) Expect(linkV6.WireguardPeers).To(HaveKey(keyV6_peer1)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: 1, Dst: &ipnetV6_3, Type: syscall.RTN_THROW, @@ -1924,12 +1930,12 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wg.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wg.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_3)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplane.WireguardConfigUpdated).To(BeTrue()) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, Dst: &ipnet_3, Type: syscall.RTN_THROW, Protocol: FelixRouteProtocol, @@ -1980,12 +1986,12 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgV6.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplaneV6.WireguardConfigUpdated).To(BeTrue()) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: 1, Dst: &ipnetV6_3, Type: syscall.RTN_THROW, @@ -2040,14 +2046,14 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wg.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wg.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_3)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplane.WireguardConfigUpdated).To(BeTrue()) Expect(link.WireguardPeers).To(HaveLen(1)) Expect(link.WireguardPeers).To(HaveKey(key_peer1)) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, Dst: &ipnet_3, Type: syscall.RTN_THROW, Protocol: FelixRouteProtocol, @@ -2063,15 +2069,15 @@ func describeEnableTests(enableV4, enableV6 bool) { err = wg.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wg.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_3)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplane.WireguardConfigUpdated).To(BeTrue()) Expect(link.WireguardPeers).To(HaveLen(2)) Expect(link.WireguardPeers).To(HaveKey(key_peer1)) Expect(link.WireguardPeers).To(HaveKey(key_peer2)) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: link.LinkAttrs.Index, Dst: &ipnet_3, Type: syscall.RTN_UNICAST, @@ -2091,14 +2097,14 @@ func describeEnableTests(enableV4, enableV6 bool) { err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgV6.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplaneV6.WireguardConfigUpdated).To(BeTrue()) Expect(linkV6.WireguardPeers).To(HaveLen(1)) Expect(linkV6.WireguardPeers).To(HaveKey(keyV6_peer1)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: 1, Dst: &ipnetV6_3, Type: syscall.RTN_THROW, @@ -2115,15 +2121,15 @@ func describeEnableTests(enableV4, enableV6 bool) { err = wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(wgV6.DebugNodes()).To(HaveLen(4)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) Expect(wgDataplaneV6.WireguardConfigUpdated).To(BeTrue()) Expect(linkV6.WireguardPeers).To(HaveLen(2)) Expect(linkV6.WireguardPeers).To(HaveKey(keyV6_peer1)) Expect(linkV6.WireguardPeers).To(HaveKey(keyV6_peer2)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: linkV6.LinkAttrs.Index, Dst: &ipnetV6_3, Type: syscall.RTN_UNICAST, @@ -2229,9 +2235,10 @@ func describeEnableTests(enableV4, enableV6 bool) { By("Applying deletion and IP moving to local host") err := wg.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_3)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.DeletedRouteKeys).To(BeEmpty()) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_3)) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, Dst: &ipnet_3, Type: syscall.RTN_THROW, Protocol: FelixRouteProtocol, @@ -2258,6 +2265,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: link.LinkAttrs.Index, Dst: &ipnet_3, Type: syscall.RTN_UNICAST, @@ -2276,9 +2284,10 @@ func describeEnableTests(enableV4, enableV6 bool) { By("Applying deletion and IP moving to local host") err := wgV6.Apply() Expect(err).NotTo(HaveOccurred()) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_3)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(BeEmpty()) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_3)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: 1, Dst: &ipnetV6_3, Type: syscall.RTN_THROW, @@ -2294,7 +2303,6 @@ func describeEnableTests(enableV4, enableV6 bool) { err = wgV6.Apply() Expect(err).NotTo(HaveOccurred()) Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(0)) Expect(rtDataplaneV6.RouteKeyToRoute).NotTo(HaveKey(routekeyV6_3)) By("Applying the same route to be remote") @@ -2306,6 +2314,7 @@ func describeEnableTests(enableV4, enableV6 bool) { Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: linkV6.LinkAttrs.Index, Dst: &ipnetV6_3, Type: syscall.RTN_UNICAST, @@ -2380,11 +2389,11 @@ func describeEnableTests(enableV4, enableV6 bool) { It("should reprogram the route to the non-wireguard peer only", func() { if enableV4 { - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_3)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_3)) Expect(rtDataplane.RouteKeyToRoute[routekey_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET, Dst: &ipnet_3, Type: syscall.RTN_THROW, Protocol: FelixRouteProtocol, @@ -2393,11 +2402,11 @@ func describeEnableTests(enableV4, enableV6 bool) { })) } if enableV6 { - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_3)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_3)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_3]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: 1, Dst: &ipnetV6_3, Type: syscall.RTN_THROW, @@ -2492,11 +2501,11 @@ func describeEnableTests(enableV4, enableV6 bool) { It("should reprogram the route to peer3 only", func() { if enableV4 { routekey_4 := fmt.Sprintf("%d-%s", tableIndex, cidr_4) - Expect(rtDataplane.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplane.DeletedRouteKeys).To(HaveKey(routekey_4)) - Expect(rtDataplane.AddedRouteKeys).To(HaveKey(routekey_4)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplane.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplane.UpdatedRouteKeys).To(HaveKey(routekey_4)) Expect(rtDataplane.RouteKeyToRoute[routekey_4]).To(Equal(netlink.Route{ + Family: unix.AF_INET, LinkIndex: link.LinkAttrs.Index, Dst: &ipnet_4, Type: syscall.RTN_UNICAST, @@ -2507,11 +2516,11 @@ func describeEnableTests(enableV4, enableV6 bool) { } if enableV6 { routekeyV6_4 := fmt.Sprintf("%d-%s", tableIndex, cidrV6_4) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(1)) - Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveKey(routekeyV6_4)) - Expect(rtDataplaneV6.AddedRouteKeys).To(HaveKey(routekeyV6_4)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveLen(1)) + Expect(rtDataplaneV6.DeletedRouteKeys).To(HaveLen(0)) + Expect(rtDataplaneV6.UpdatedRouteKeys).To(HaveKey(routekeyV6_4)) Expect(rtDataplaneV6.RouteKeyToRoute[routekeyV6_4]).To(Equal(netlink.Route{ + Family: unix.AF_INET6, LinkIndex: linkV6.LinkAttrs.Index, Dst: &ipnetV6_4, Type: syscall.RTN_UNICAST, @@ -2745,7 +2754,7 @@ func describeEnableTests(enableV4, enableV6 bool) { // Set the interface to be up wgDataplane.SetIface(ifaceName, true, true) rtDataplane.AddIface(link.LinkAttrs.Index, ifaceName, true, true) - wg.OnIfaceStateChanged(ifaceName, ifacemonitor.StateUp) + wg.OnIfaceStateChanged(ifaceName, link.LinkAttrs.Index, ifacemonitor.StateUp) err = apply.Apply() Expect(err).NotTo(HaveOccurred()) @@ -2801,7 +2810,7 @@ func describeEnableTests(enableV4, enableV6 bool) { // Set the interface to be up wgDataplaneV6.SetIface(ifaceNameV6, true, true) rtDataplaneV6.AddIface(linkV6.LinkAttrs.Index, ifaceNameV6, true, true) - wgV6.OnIfaceStateChanged(ifaceNameV6, ifacemonitor.StateUp) + wgV6.OnIfaceStateChanged(ifaceNameV6, linkV6.LinkAttrs.Index, ifacemonitor.StateUp) err = apply.Apply() Expect(err).NotTo(HaveOccurred()) diff --git a/go.mod b/go.mod index aad3f9bae99..5a044bd8863 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.22.3 require ( github.com/BurntSushi/toml v1.3.2 + github.com/Masterminds/semver/v3 v3.2.1 github.com/Microsoft/hcsshim v0.11.6 github.com/apparentlymart/go-cidr v1.1.0 github.com/aws/aws-sdk-go-v2 v1.25.0 @@ -11,12 +12,15 @@ require ( github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 github.com/aws/aws-sdk-go-v2/service/ec2 v1.148.0 github.com/aws/smithy-go v1.20.0 + github.com/bits-and-blooms/bitset v1.13.0 github.com/buger/jsonparser v1.1.1 github.com/container-storage-interface/spec v1.9.0 github.com/containernetworking/cni v1.2.0 github.com/containernetworking/plugins v1.1.1 github.com/coreos/go-semver v0.3.1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc + github.com/docker/distribution v2.8.2+incompatible + github.com/docker/docker v27.1.1+incompatible github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 github.com/envoyproxy/go-control-plane v0.12.0 github.com/fsnotify/fsnotify v1.7.0 @@ -28,6 +32,7 @@ require ( github.com/golang/snappy v0.0.4 github.com/google/btree v1.1.2 github.com/google/go-cmp v0.6.0 + github.com/google/go-github/v53 v53.2.0 github.com/google/gopacket v1.1.19 github.com/google/netstack v0.0.0-20191123085552-55fcc16cd0eb github.com/google/safetext v0.0.0-20230106111101-7156a760e523 @@ -60,54 +65,57 @@ require ( github.com/prometheus/client_golang v1.18.0 github.com/prometheus/client_model v0.6.0 github.com/prometheus/common v0.47.0 - github.com/rakelkar/gonetsh v0.3.2 + github.com/prometheus/procfs v0.12.0 github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 github.com/shirou/gopsutil v0.0.0-20190323131628-2cbc9195c892 github.com/sirupsen/logrus v1.9.3 + github.com/slack-go/slack v0.14.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.2 + github.com/stretchr/testify v1.9.0 github.com/tchap/go-patricia/v2 v2.3.1 github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae + github.com/urfave/cli/v2 v2.27.3 github.com/vishvananda/netlink v1.2.1-beta.2.0.20240703200800-b54f85093f4a go.etcd.io/etcd/api/v3 v3.5.12 go.etcd.io/etcd/client/pkg/v3 v3.5.12 go.etcd.io/etcd/client/v2 v2.305.12 go.etcd.io/etcd/client/v3 v3.5.12 - golang.org/x/crypto v0.22.0 - golang.org/x/net v0.24.0 + golang.org/x/crypto v0.24.0 + golang.org/x/net v0.26.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 - golang.org/x/text v0.14.0 + golang.org/x/sys v0.21.0 + golang.org/x/text v0.16.0 golang.org/x/time v0.5.0 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200324154536-ceff61240acf - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f - google.golang.org/grpc v1.61.1 + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 + google.golang.org/grpc v1.65.0 gopkg.in/go-playground/validator.v9 v9.30.2 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.28.9 - k8s.io/apiextensions-apiserver v0.28.9 - k8s.io/apimachinery v0.28.9 - k8s.io/apiserver v0.28.9 - k8s.io/client-go v0.28.9 - k8s.io/code-generator v0.28.9 - k8s.io/component-base v0.28.9 + k8s.io/api v0.29.9 + k8s.io/apiextensions-apiserver v0.29.9 + k8s.io/apimachinery v0.29.9 + k8s.io/apiserver v0.29.9 + k8s.io/client-go v0.29.9 + k8s.io/code-generator v0.29.9 + k8s.io/component-base v0.29.9 k8s.io/klog/v2 v2.120.1 - k8s.io/kube-aggregator v0.28.9 - k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 - k8s.io/kubernetes v1.28.9 + k8s.io/kube-aggregator v0.29.9 + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 + k8s.io/kubernetes v1.29.9 k8s.io/utils v0.0.0-20240310230437-4693a0247e57 modernc.org/memory v1.7.2 - sigs.k8s.io/controller-runtime v0.15.3 + sigs.k8s.io/controller-runtime v0.17.0 sigs.k8s.io/kind v0.22.0 sigs.k8s.io/knftables v0.0.15 + sigs.k8s.io/network-policy-api v0.1.5 sigs.k8s.io/yaml v1.4.0 ) require ( - cloud.google.com/go/compute v1.23.3 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect @@ -122,6 +130,7 @@ require ( github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/alexflint/go-filemutex v1.1.0 // indirect @@ -140,31 +149,33 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/boombuler/barcode v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/checkpoint-restore/go-criu/v5 v5.3.0 // indirect github.com/cilium/ebpf v0.9.1 // indirect - github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 // indirect + github.com/cloudflare/circl v1.3.9 // indirect + github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/console v1.0.3 // indirect github.com/containerd/containerd v1.6.26 // indirect github.com/containerd/ttrpc v1.2.2 // indirect github.com/coreos/go-iptables v0.6.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect @@ -174,21 +185,23 @@ require ( github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace // indirect github.com/go-sql-driver/mysql v1.4.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/godbus/dbus/v5 v5.0.6 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/google/cadvisor v0.47.3 // indirect - github.com/google/cel-go v0.16.1 // indirect + github.com/google/cadvisor v0.48.1 // indirect + github.com/google/cel-go v0.17.7 // indirect github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.2 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/gruntwork-io/go-commons v0.8.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -203,14 +216,14 @@ require ( github.com/lithammer/dedent v1.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect github.com/mdlayher/genetlink v1.0.0 // indirect github.com/mdlayher/netlink v1.1.0 // indirect github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/ipvs v1.1.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -221,14 +234,15 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/runc v1.1.12 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opencontainers/runc v1.1.14 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 // indirect - github.com/opencontainers/selinux v1.10.1 // indirect + github.com/opencontainers/selinux v1.11.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pquerna/otp v1.2.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect @@ -239,37 +253,37 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect github.com/urfave/cli v1.22.4 // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/vmware/govmomi v0.30.6 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.46.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect - go.uber.org/atomic v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect + go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.zx2c4.com/wireguard v0.0.20200121 // indirect - google.golang.org/api v0.153.0 // indirect + google.golang.org/api v0.169.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/gcfg.v1 v1.2.3 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -277,59 +291,59 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/cloud-provider v0.28.9 // indirect - k8s.io/component-helpers v0.28.9 // indirect - k8s.io/controller-manager v0.28.9 // indirect - k8s.io/cri-api v0.28.9 // indirect + k8s.io/cloud-provider v0.29.9 // indirect + k8s.io/component-helpers v0.29.9 // indirect + k8s.io/controller-manager v0.29.9 // indirect + k8s.io/cri-api v0.29.9 // indirect k8s.io/csi-translation-lib v0.28.9 // indirect k8s.io/dynamic-resource-allocation v0.28.9 // indirect - k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect - k8s.io/kms v0.28.9 // indirect + k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect + k8s.io/kms v0.29.9 // indirect k8s.io/kube-scheduler v0.0.0 // indirect - k8s.io/kubectl v0.0.0 // indirect + k8s.io/kubectl v0.26.0 // indirect k8s.io/kubelet v0.28.9 // indirect k8s.io/legacy-cloud-providers v0.0.0 // indirect k8s.io/mount-utils v0.28.9 // indirect - k8s.io/pod-security-admission v0.0.0 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect + k8s.io/pod-security-admission v0.26.0 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) replace ( github.com/projectcalico/api => ./api - k8s.io/api => k8s.io/api v0.28.9 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.28.9 - k8s.io/apimachinery => k8s.io/apimachinery v0.28.9 - k8s.io/apiserver => k8s.io/apiserver v0.28.9 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.28.9 - k8s.io/client-go => k8s.io/client-go v0.28.9 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.28.9 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.28.9 - k8s.io/code-generator => k8s.io/code-generator v0.28.9 - k8s.io/component-base => k8s.io/component-base v0.28.9 - k8s.io/component-helpers => k8s.io/component-helpers v0.28.9 - k8s.io/controller-manager => k8s.io/controller-manager v0.28.9 - k8s.io/cri-api => k8s.io/cri-api v0.28.9 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.28.9 - k8s.io/endpointslice => k8s.io/endpointslice v0.28.9 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.28.9 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.28.9 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.28.9 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.28.9 - k8s.io/kubectl => k8s.io/kubectl v0.28.9 - k8s.io/kubelet => k8s.io/kubelet v0.28.9 + k8s.io/api => k8s.io/api v0.29.9 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.29.9 + k8s.io/apimachinery => k8s.io/apimachinery v0.29.9 + k8s.io/apiserver => k8s.io/apiserver v0.29.9 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.29.9 + k8s.io/client-go => k8s.io/client-go v0.29.9 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.29.9 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.29.9 + k8s.io/code-generator => k8s.io/code-generator v0.29.9 + k8s.io/component-base => k8s.io/component-base v0.29.9 + k8s.io/component-helpers => k8s.io/component-helpers v0.29.9 + k8s.io/controller-manager => k8s.io/controller-manager v0.29.9 + k8s.io/cri-api => k8s.io/cri-api v0.29.9 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.29.9 + k8s.io/endpointslice => k8s.io/endpointslice v0.29.9 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.29.9 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.29.9 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.29.9 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.29.9 + k8s.io/kubectl => k8s.io/kubectl v0.29.9 + k8s.io/kubelet => k8s.io/kubelet v0.29.9 // Need replacements for all the k8s subsidiary projects that are pulled in indirectly because // the kubernets repo pulls them in via a replacement to its own vendored copies, which doesn't work for // transient imports. - k8s.io/kubernetes => k8s.io/kubernetes v1.28.9 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.28.9 - k8s.io/metrics => k8s.io/metrics v0.28.9 - k8s.io/mount-utils => k8s.io/mount-utils v0.28.9 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.28.9 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.28.9 + k8s.io/kubernetes => k8s.io/kubernetes v1.29.9 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.29.9 + k8s.io/metrics => k8s.io/metrics v0.29.9 + k8s.io/mount-utils => k8s.io/mount-utils v0.29.9 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.29.9 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.9 // Use an untagged knftables version that has changes we need. sigs.k8s.io/knftables => sigs.k8s.io/knftables v0.0.17-0.20240627140917-8d2660d78107 diff --git a/go.sum b/go.sum index a9dbea4bbc5..2617c39b5df 100644 --- a/go.sum +++ b/go.sum @@ -31,10 +31,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -82,7 +80,8 @@ github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1 github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.11.6 h1:qxVO1cqHMQFm11vXklhRIYu/qiukJCqccjQAOddolvk= @@ -90,14 +89,11 @@ github.com/Microsoft/hcsshim v0.11.6/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 h1:UUppSQnhf4Yc6xGxSkoQpPhb7RVzuv5Nb1mwJ5VId9s= github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/alexflint/go-filemutex v1.1.0 h1:IAWuUuRYL2hETx5b8vCgwnD+xSdlsTQY6s2JjBsqLdg= @@ -105,7 +101,6 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= -github.com/antoninbas/go-powershell v0.1.0/go.mod h1:01pgKhz1CJxGnCWqXVDgvmp/QmHgWgEdxdYP+1azopE= github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= @@ -114,7 +109,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBWDSQ= @@ -145,29 +139,25 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 h1:cjTRjh700H36MQ8M0LnDn33W3Jmw github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ= github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= @@ -175,20 +165,18 @@ github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAc github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4= github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= +github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= +github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/container-storage-interface/spec v1.9.0 h1:zKtX4STsq31Knz3gciCYCi1SXtO2HJDecIjDVboYavY= github.com/container-storage-interface/spec v1.9.0/go.mod h1:ZfDu+3ZRyeVqxZM0Ds19MVLkN2d1XJ5MAfi1L3VjlT0= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= @@ -197,7 +185,8 @@ github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARu github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs= github.com/containerd/containerd v1.6.26/go.mod h1:I4TRdsdoo5MlKob5khDJS2EPT1l1oMNaE2MBm6FrwxM= -github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtOs= github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak= github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= @@ -210,33 +199,30 @@ github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= +github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= @@ -252,18 +238,18 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= @@ -271,7 +257,6 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -288,24 +273,15 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= @@ -321,19 +297,18 @@ github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= +github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= @@ -342,8 +317,6 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -385,10 +358,10 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cadvisor v0.47.3 h1:5XKTHBduWlBjmgw07uwEiC+Xa/FRd0MZI37oqlTagO0= -github.com/google/cadvisor v0.47.3/go.mod h1:iJdTjcjyKHjLCf7OSTzwP5GxdfrkPusw2x5bwGvuLUw= -github.com/google/cel-go v0.16.1 h1:3hZfSNiAU3KOiNtxuFXVp5WFy4hf/Ly3Sa4/7F8SXNo= -github.com/google/cel-go v0.16.1/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= +github.com/google/cadvisor v0.48.1 h1:eyYTxKBd+KxI1kh6rst4JSTLUhfHQM34qGpp+0AMlSg= +github.com/google/cadvisor v0.48.1/go.mod h1:ZkYbiiVdyoqBmI2ahZI8GlmirT78OAOER0z4EQugkxQ= +github.com/google/cel-go v0.17.7 h1:6ebJFzu1xO2n7TLtN+UBqShGBhlD85bhvglh5DpcfqQ= +github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -403,10 +376,14 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= +github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -452,10 +429,11 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= @@ -464,8 +442,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro= github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= github.com/gruntwork-io/terratest v0.46.7 h1:oqGPBBO87SEsvBYaA0R5xOq+Lm2Xc5dmFVfxEolfZeU= @@ -501,13 +479,9 @@ github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9q github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4 h1:nwOc1YaOrYJ37sEBrtWZrdqzK22hiJs3GpDmP3sR2Yw= github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -532,8 +506,6 @@ github.com/juju/utils/v3 v3.0.0-20220130232349-cd7ecef0e94a h1:5ZWDCeCF0RaITrZGe github.com/juju/utils/v3 v3.0.0-20220130232349-cd7ecef0e94a/go.mod h1:LzwbbEN7buYjySp4nqnti6c6olSqRXUk6RkbSUUP1n8= github.com/juju/version/v2 v2.0.0-20211007103408-2e8da085dc23 h1:wtEPbidt1VyHlb8RSztU6ySQj29FLsOQiI9XiJhXDM4= github.com/juju/version/v2 v2.0.0-20211007103408-2e8da085dc23/go.mod h1:Ljlbryh9sYaUSGXucslAEDf0A2XUSGvDbHJgW8ps6nc= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= @@ -545,8 +517,6 @@ github.com/kelseyhightower/memkv v0.1.1/go.mod h1:uIeINg0Dy2aioPWSdga9VnueJjfSvu github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -574,15 +544,13 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg= github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg= github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0= @@ -603,11 +571,10 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/ipvs v1.1.0 h1:ONN4pGaZQgAx+1Scz5RvWV4Q7Gb+mvfRh3NsPS+1XQQ= -github.com/moby/ipvs v1.1.0/go.mod h1:4VJMWuf098bsUMmZEiD4Tjk/O7mOn3l1PTD3s4OoYAs= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= @@ -615,22 +582,18 @@ github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbD github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb h1:e+l77LJOEqXTIQihQJVkA6ZxPOUmfPM5e4H7rcpgtSk= github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm/Q= github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A= @@ -655,18 +618,14 @@ github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= -github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= -github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= +github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R5M2qXZiK/mWPMT4VldCOiSL9HIAMuxQZWdG0CSM5+4= github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opencontainers/selinux v1.10.1 h1:09LIPVRP3uuZGQvgR+SgMSNBd1Eb3vlRbGqQpoHsF8w= -github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= +github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -676,7 +635,6 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -689,44 +647,22 @@ github.com/projectcalico/go-json v0.0.0-20161128004156-6219dc7339ba h1:aaF2byUCZ github.com/projectcalico/go-json v0.0.0-20161128004156-6219dc7339ba/go.mod h1:q8EdCgBdMQzgiX/uk4GXLWLk+gIHd1a7mWUAamJKDb4= github.com/projectcalico/go-yaml-wrapper v0.0.0-20191112210931-090425220c54 h1:Jt2Pic9dxgJisekm8q2WV9FaWxUJhhRfwHSP640drww= github.com/projectcalico/go-yaml-wrapper v0.0.0-20191112210931-090425220c54/go.mod h1:UgC0aTQ2KMDxlX3lU/stndk7DMUBJqzN40yFiILHgxc= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rakelkar/gonetsh v0.3.2 h1:ebvU73nAFQ4zUF28hATOprT1CIhZPrVE9Rs/xN6F6Q4= -github.com/rakelkar/gonetsh v0.3.2/go.mod h1:MkEXf5yV9DRTy8TfpWdvMuCTkxajNE/0tn9pvZ6ikDw= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 h1:if3/24+h9Sq6eDx8UUz1SO9cT9tizyIsATfB7b4D3tc= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -738,7 +674,6 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY= github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shirou/gopsutil v0.0.0-20190323131628-2cbc9195c892 h1:oiNB/s36DdNBEnulbhdj6zHS73U/wRQihnsoJwanqfM= @@ -746,19 +681,17 @@ github.com/shirou/gopsutil v0.0.0-20190323131628-2cbc9195c892/go.mod h1:WWnYX4lz github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slack-go/slack v0.14.0 h1:6c0UTfbRnvRssZUsZ2qe0Iu07VAMPjRqOa6oX8ewF4k= +github.com/slack-go/slack v0.14.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -766,7 +699,6 @@ github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= @@ -776,8 +708,9 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -788,8 +721,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= @@ -800,14 +734,13 @@ github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae h1:vgGSvdW5Lqg+I1 github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae/go.mod h1:quDq6Se6jlGwiIKia/itDZxqC5rj6/8OdFyMMAwTxCs= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/urfave/cli/v2 v2.27.3 h1:/POWahRmdh7uztQ3CYnaDddk0Rm90PyOgIxgW2rr41M= +github.com/urfave/cli/v2 v2.27.3/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= github.com/vishvananda/netlink v1.2.1-beta.2.0.20240703200800-b54f85093f4a h1:n9iF7t9sLw43CwPLvPZkCfsFEGvoR2A63W8OEjuQqJ4= github.com/vishvananda/netlink v1.2.1-beta.2.0.20240703200800-b54f85093f4a/go.mod h1:whJevzBpTrid75eZy99s3DqCmy05NfibNaF2Ol5Ox5A= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= @@ -817,14 +750,16 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= @@ -833,12 +768,12 @@ go.etcd.io/etcd/client/v2 v2.305.12 h1:0m4ovXYo1CHaA/Mp3X/Fak5sRNIWf01wk/X1/G3sG go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E= go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= -go.etcd.io/etcd/pkg/v3 v3.5.9 h1:6R2jg/aWd/zB9+9JxmijDKStGJAPFsX3e6BeJkMi6eQ= -go.etcd.io/etcd/pkg/v3 v3.5.9/go.mod h1:BZl0SAShQFk0IpLWR78T/+pyt8AruMHhTNNX73hkNVY= -go.etcd.io/etcd/raft/v3 v3.5.9 h1:ZZ1GIHoUlHsn0QVqiRysAm3/81Xx7+i2d7nSdWxlOiI= -go.etcd.io/etcd/raft/v3 v3.5.9/go.mod h1:WnFkqzFdZua4LVlVXQEGhmooLeyS7mqzS4Pf4BCVqXg= -go.etcd.io/etcd/server/v3 v3.5.9 h1:vomEmmxeztLtS5OEH7d0hBAg4cjVIu9wXuNzUZx2ZA0= -go.etcd.io/etcd/server/v3 v3.5.9/go.mod h1:GgI1fQClQCFIzuVjlvdbMxNbnISt90gdfYyqiAIt65g= +go.etcd.io/etcd/pkg/v3 v3.5.10 h1:WPR8K0e9kWl1gAhB5A7gEa5ZBTNkT9NdNWrR8Qpo1CM= +go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs= +go.etcd.io/etcd/raft/v3 v3.5.10 h1:cgNAYe7xrsrn/5kXMSaH8kM/Ky8mAdMqGOxyYwpP0LA= +go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc= +go.etcd.io/etcd/server/v3 v3.5.10 h1:4NOGyOwD5sUZ22PiWYKmfxqoeh72z6EhYjNosKGLmZg= +go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -850,38 +785,37 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.46.1 h1:6l13V1yADBiPaUz+tExvNHHO2jF9RbxZsmea3POmlmc= go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.46.1/go.mod h1:lqAQ/iU6CDKDWb73W3wNIit+0uL8EIqli8CdBdnThVo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/contrib/propagators/b3 v1.21.1 h1:WPYiUgmw3+b7b3sQ1bFBFAf0q+Di9dvNc3AtYfnT4RQ= go.opentelemetry.io/contrib/propagators/b3 v1.21.1/go.mod h1:EmzokPoSqsYMBVK4nRnhsfm5mbn8J1eDuz/U1UaQaWg= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -892,8 +826,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -932,12 +866,11 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -945,7 +878,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -971,21 +903,17 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1002,9 +930,8 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1016,14 +943,11 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1033,22 +957,18 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1062,8 +982,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1081,36 +999,30 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1121,11 +1033,9 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1142,7 +1052,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1188,8 +1097,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1198,8 +1107,6 @@ golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTB golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200324154536-ceff61240acf h1:rWUZHukj3poXegPQMZOXgxjTGIBe3mLNHNVvL5DsHus= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200324154536-ceff61240acf/go.mod h1:UdS9frhv65KTfwxME1xE8+rHYoFpbm36gOud1GhBe9c= -gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= -gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1230,8 +1137,8 @@ google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1298,13 +1205,12 @@ google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1330,10 +1236,8 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= -google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1348,11 +1252,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1379,11 +1280,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -1391,7 +1290,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1399,70 +1299,66 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.28.9 h1:E7VEXXCAlSrp+08zq4zgd+ko6Ttu0Mw+XoXlIkDTVW0= -k8s.io/api v0.28.9/go.mod h1:AnCsDYf3SHjfa8mPG5LGYf+iF4mie+3peLQR51MMCgw= -k8s.io/apiextensions-apiserver v0.28.9 h1:yzPHp+4IASHeu7XIPkAKJrY4UjWdjiAjOcQMd6oNKj0= -k8s.io/apiextensions-apiserver v0.28.9/go.mod h1:Rjhvq5y3JESdZgV2UOByldyefCfRrUguVpBLYOAIbVs= -k8s.io/apimachinery v0.28.9 h1:aXz4Zxsw+Pk4KhBerAtKRxNN1uSMWKfciL/iOdBfXvA= -k8s.io/apimachinery v0.28.9/go.mod h1:zUG757HaKs6Dc3iGtKjzIpBfqTM4yiRsEe3/E7NX15o= -k8s.io/apiserver v0.28.9 h1:koPXvgSXRBDxKJQjJGdZNgPsT9lQv6scJJFipd1m86E= -k8s.io/apiserver v0.28.9/go.mod h1:D51I37WBZojJhmLcjNVE4GSVrjiUHP+yq+N5KvKn2wY= -k8s.io/cli-runtime v0.28.9 h1:TfEV/UgCiXewliUHOHsUMZ1bfENhqcqKkA/hqQ/HwvQ= -k8s.io/cli-runtime v0.28.9/go.mod h1:PgxW97xCDbtWgsuo2nahMc2/MxcSDgscdwm8XZ7973A= -k8s.io/client-go v0.28.9 h1:mmMvejwc/KDjMLmDpyaxkWNzlWRCJ6ht7Qsbsnwn39Y= -k8s.io/client-go v0.28.9/go.mod h1:GFDy3rUNId++WGrr0hRaBrs+y1eZz5JtVZODEalhRMo= -k8s.io/cloud-provider v0.28.9 h1:FBW4Ii1NdXCHKprzkM8/s5BpxvLgJmYrZTNJABsVX7Y= -k8s.io/cloud-provider v0.28.9/go.mod h1:7tFyiftAlSARvJS6mzZQQKKDQA81asNQ2usg35R3Exo= -k8s.io/cluster-bootstrap v0.28.9 h1:MxyJszYYyWEGNrmkv/vxZ8HJUgmb1ACS9PzMb7xzrn4= -k8s.io/cluster-bootstrap v0.28.9/go.mod h1:feeH01O2+GaGfi86gzQh0JpevSyzuXOg0TXj/UHGLdE= -k8s.io/code-generator v0.28.9 h1:NyZt4+equopQNbwjSSpVikB15U4ghmvIaqn+VWd367U= -k8s.io/code-generator v0.28.9/go.mod h1:WiJgVNDFAlT90nq6IOxhZ1gxL2JexbcfAx9ZBsyQ3Do= -k8s.io/component-base v0.28.9 h1:ySM2PR8Z/xaUSG1Akd3yM6dqUezTltI7S5aV41MMuuc= -k8s.io/component-base v0.28.9/go.mod h1:QtWzscEhCKRfHV24/S+11BwWjVxhC6fd3RYoEgZcWFU= -k8s.io/component-helpers v0.28.9 h1:knX9F2nRoxF4wplgXO4C5tE4/k7HGszK3177Tm4+CUc= -k8s.io/component-helpers v0.28.9/go.mod h1:TdAkLbywEDE2CB5h8LbM/W03T3k8wvqAaoPcEZrr6Z4= -k8s.io/controller-manager v0.28.9 h1:muAtmO2mDN7pDkAJQMknvWy+WQhkvvi/jK1V82+qbLw= -k8s.io/controller-manager v0.28.9/go.mod h1:RYP65K6GWLRWYZR7PRRaStfvgeXkhCGZwJsxRPuaDV0= -k8s.io/cri-api v0.28.9 h1:AlhkmIDLeKWubmX2xVkW3DhcbPwH79xauFySijfkIDU= -k8s.io/cri-api v0.28.9/go.mod h1:8/bPK3T4irPoj3LjriQc1TAIheeN2yWXR3mz+8jNZ8U= -k8s.io/csi-translation-lib v0.28.9 h1:zl93l7wk0iwKInyRJfaodvsWf1z8QtWCN9a5OqHeT3o= -k8s.io/csi-translation-lib v0.28.9/go.mod h1:eOniPQitdkuyVh+gtktg3yeDJQu/IidIUSMadDPLhak= +k8s.io/api v0.29.9 h1:FwdflpNsfMUYUOblMZNWJ4K/q0OSL5A4jGa0iOgcJco= +k8s.io/api v0.29.9/go.mod h1:fNhmzRfKaSEHCmczA/jRx6CiDKhYOnFLJBERMJAXEk8= +k8s.io/apiextensions-apiserver v0.29.9 h1:EB6RK06kFJjbzBwU1YiVznxrcgBE0hhDWt6EQQIcOy4= +k8s.io/apiextensions-apiserver v0.29.9/go.mod h1:jcaHG6R/bB1iU6XzC1DMhB1x2ktTJLt2KKpg6B65Z2c= +k8s.io/apimachinery v0.29.9 h1:YZ8HUid1TzQVz94cnNlsQjLdH0VoAhWSqz7t0q6B12A= +k8s.io/apimachinery v0.29.9/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= +k8s.io/apiserver v0.29.9 h1:BiHTZbAYcNYHTE9RlWMBe5AX2XoZbRujy6oo5krU4V8= +k8s.io/apiserver v0.29.9/go.mod h1:3zmBeYworciVZHs8jSfzt/naTpDQb3AM++aYJ5Pkqqo= +k8s.io/cli-runtime v0.29.9 h1:rryHH2SZtZePv0gj9RM5ftXYcK8v2jbMLOzbORnzzw4= +k8s.io/cli-runtime v0.29.9/go.mod h1:IHgU0jdyAOcrfkpvaDXZRqPe+RJYlUgbufl88Z6EUyo= +k8s.io/client-go v0.29.9 h1:4f/Wz6li3rEyIPFj32XAQMtOGMM1tg7KQi1oeS6ibPg= +k8s.io/client-go v0.29.9/go.mod h1:2N1drQEZ5yiYrWVaE2Un8JiISUhl47D8pyZlYLszke4= +k8s.io/cloud-provider v0.29.9 h1:sbu1is+Hq6/l7SlgBdy6Vc9fEtQysLBPTu3qgmPXU44= +k8s.io/cloud-provider v0.29.9/go.mod h1:fTOTtMu+SMa9oTeAsPtkliICKp2t/4a0DEXeOwrrhnc= +k8s.io/cluster-bootstrap v0.29.9 h1:iLg4LjZV2BqPPMuXe2YAHhdkR88U8TX8VdyvlJyebT4= +k8s.io/cluster-bootstrap v0.29.9/go.mod h1:dOOvfAdaqFP3n3+5HXyBpPRJi17RgOP7vs+ulGRi03Y= +k8s.io/code-generator v0.29.9 h1:57k53ZbD4W4NFlTV2iH7nKfmoLP4Q6yW2o2H2nyZpF0= +k8s.io/code-generator v0.29.9/go.mod h1:7TYnI0dYItL2cKuhhgPSuF3WED9uMdELgbVXFfn/joE= +k8s.io/component-base v0.29.9 h1:lPENvp3CCwdeMEWGjiTfn5b287qQYuK7gX32OBOovmA= +k8s.io/component-base v0.29.9/go.mod h1:NGDa6Ih0EdcLA2G4K2ZYySoiB+2Tn+rmSqPyudCPgDY= +k8s.io/component-helpers v0.29.9 h1:+3dLb8nHWPeNwrL6whkpvKv46o90EW5O6Aju/hLQW70= +k8s.io/component-helpers v0.29.9/go.mod h1:sUtoToDUdZDku0Kj4i3dRWyb1jmZLxXO2cvWvD27A40= +k8s.io/controller-manager v0.29.9 h1:hKGqtTf7IDmN5csLVgf6VUXPJqosajAnMsqw2jCDh6s= +k8s.io/controller-manager v0.29.9/go.mod h1:OZVIb2E9QFoSaiaVt4DFOsH/kZpCaEgFSYr/mCF9zuk= +k8s.io/cri-api v0.29.9 h1:U1YH8RepiYgrbMGMuiopEaEbILdfxO6L92A6b19ZdOc= +k8s.io/cri-api v0.29.9/go.mod h1:A6pdbjzML2xi9B0Clqn5qt1HJ3Ik12x2j+jv/TkqjRE= +k8s.io/csi-translation-lib v0.29.9 h1:i2PQz5/V7acA96Iz5SOWG5UvM2j1HWdHdWVb11GJGZo= +k8s.io/csi-translation-lib v0.29.9/go.mod h1:Rcpr7dv/mmtLF+SGJPuJUwjIby9OjNQj7u9vMpDT248= k8s.io/dynamic-resource-allocation v0.28.9 h1:u3upC0ah0eNrO1uh3yUL3VefvB1OUTNQLKjxMfe1pgc= k8s.io/dynamic-resource-allocation v0.28.9/go.mod h1:SIwpYxFh5gk7bW1dZ+GgnA6l4VmhrnUugePlLxYva+4= -k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= -k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= +k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.28.9 h1:ApCWJulBl+uFRTr2jtTpG1lffmqqMuLnOH/RUbtO4UY= -k8s.io/kms v0.28.9/go.mod h1:VgyAIRMFqZX9lHyixecU/JTI0wnPD1wCIlquvlXRJ+Y= -k8s.io/kube-aggregator v0.28.9 h1:1B3J8AF4uuF1PIXiWvYHjKMUpVHm6Bk6VCs+/PDmonQ= -k8s.io/kube-aggregator v0.28.9/go.mod h1:o5FBctFFpjuzFWO8fIjdO3Us1ZLQKHIcj20N5h/Aap0= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= -k8s.io/kube-scheduler v0.28.9 h1:rRFkTBiPIpcCdyI7/E2HVyzWehmSW1eI/rWyKTVrKfk= -k8s.io/kube-scheduler v0.28.9/go.mod h1:9xnBlTE/B2EwfiUZ/uh2zBEVViRhGG+ojLiMvyxXCe8= -k8s.io/kubectl v0.28.9 h1:FTf/aapuuFxPmt8gYUeqUmcsgG0gKC2ei6n+TO5sGOw= -k8s.io/kubectl v0.28.9/go.mod h1:ip/zTUr1MM/H2M+YbPHnSKLt0x6kb85SJtRSjwEGDfs= -k8s.io/kubelet v0.28.9 h1:76v00fFLeniz27kXhGGUIxONdwa9LKcD2Jd5cXYAZko= -k8s.io/kubelet v0.28.9/go.mod h1:46P39DFjI+E59nU2OgpatyS3oWy58ClulKO6riZ/97o= -k8s.io/kubernetes v1.28.9 h1:I4sYGQJOuxEo4/QWoY7M8kDB7O0HcH266t6o6mR6ogg= -k8s.io/kubernetes v1.28.9/go.mod h1:chlmcCDBnOA/y+572cw8dO0Rci1wiA8bm5+zhPdFLCk= -k8s.io/legacy-cloud-providers v0.28.9 h1:vHbZMgBDlXdOmM/yQXGgcAZ0sp4Rr4PnPmbjR/QDmmA= -k8s.io/legacy-cloud-providers v0.28.9/go.mod h1:+tQeBWTQcdukBF7/E+y1ywXq6Bk7pBX2vG66t1Qoln8= -k8s.io/metrics v0.28.9 h1:3TAJhF1GzYK89bE1RLqDinTXAlCnI8UgciwfpKHzKfg= -k8s.io/metrics v0.28.9/go.mod h1:7Hn16jtdxc2Q6Vm73QK7nF7HiLJvomLgN7lEQs8SONs= -k8s.io/mount-utils v0.28.9 h1:RWt7xIrTzoKYKmMZ9Lh/rkZ9zreCUdpzhFe8jJXXuNQ= -k8s.io/mount-utils v0.28.9/go.mod h1:ZxAFXgKzcAyi3VTd2pKFlZFswl9Q/cveJ5aptdjQOuc= -k8s.io/pod-security-admission v0.28.9 h1:towoNqSp7aU7gF8T89zftCuQUfliyib3ds20Kz/hysg= -k8s.io/pod-security-admission v0.28.9/go.mod h1:mfEhECQ+AvP+zehqxemSq1pDL4YLoWCP7liL0YmkpZY= -k8s.io/sample-apiserver v0.28.9 h1:p3pUL93VeOQWBpLzrLTBcKMszmCKzrrz+eUsyljkPgI= -k8s.io/sample-apiserver v0.28.9/go.mod h1:xByH3mGXrF7JpDPoFE0q79Mo5y3UOoZm0h/RR7shmuM= -k8s.io/utils v0.0.0-20200410111917-5770800c2500/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/kms v0.29.9 h1:7B9VGhFAzNfBmfXeQ0Xi+OzIcNPw/xazPnLm/J3vNT4= +k8s.io/kms v0.29.9/go.mod h1:vWVImKkJd+1BQY4tBwdfSwjQBiLrnbNtHADcDEDQFtk= +k8s.io/kube-aggregator v0.29.9 h1:HM1dSymp1Io9d9hNdr3skGJvZnRPQqEU7sRpxOqmBuc= +k8s.io/kube-aggregator v0.29.9/go.mod h1:6g6HoCqjGk7F7fgjmkkHiByz3wm2G6Voyxo5B13377c= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kube-scheduler v0.29.9 h1:A0UJlogv5Bxc4rSJl1//rBTkzbOriOn6TJdhJKWsfJM= +k8s.io/kube-scheduler v0.29.9/go.mod h1:hBRa3q82xAp2kjNFTTMyq+fYSDv9nBYv+bNgQqEsSlQ= +k8s.io/kubectl v0.29.9 h1:8DJIPkRk5a6WonxRAbicJIn0DNwacOxaLxO4EDwf/hc= +k8s.io/kubectl v0.29.9/go.mod h1:ylJbHUuPTYiwxAKx97nAyU3TKh3vHlEW+Pp44Usolvw= +k8s.io/kubelet v0.29.9 h1:Qbnz4otarQi5E8Z80Y3Y8AY5wfyc6WQjUQ6hU302gPQ= +k8s.io/kubelet v0.29.9/go.mod h1:jOTCkSUkzTu6t5SvxcSDAg3n4bZy3+mCOe87WJ3NS58= +k8s.io/kubernetes v1.29.9 h1:RF5IQgliwV4fLNMH2ca9CPXGcmbLPq3olc3OBrbf7/M= +k8s.io/kubernetes v1.29.9/go.mod h1:28sDhcb87LX5z3GWAKYmLrhrifxi4W9bEWua4DRTIvk= +k8s.io/legacy-cloud-providers v0.29.9 h1:pulR8J+oxp56LJeUZ7AOA/SytQAh7nv4ZMgPT/i9Vcw= +k8s.io/legacy-cloud-providers v0.29.9/go.mod h1:nG4mjSAbqeJaK4LaOXADZjI/wdFozrjxu91G8Q+c8B8= +k8s.io/metrics v0.29.9 h1:0Rglc03f5u4/wHliG8cfhLOtSbTwL03WQ37CMn9c4OI= +k8s.io/metrics v0.29.9/go.mod h1:1DixHaqPn7puV31YlEKT/kAEP+31cpOShIPiRtro5no= +k8s.io/mount-utils v0.29.9 h1:q3lNnDO98L7PW6d2X/YtXTGV2iaMiQyEVR8JzuRknfk= +k8s.io/mount-utils v0.29.9/go.mod h1:SHUMR9n3b6tLgEmlyT36cL6fV6Sjwa5CJhc0guCXvb0= +k8s.io/pod-security-admission v0.29.9 h1:f3b2L3pUR8a2m+h9LshJqoQGL6E5tf312qXC2FT+9cw= +k8s.io/pod-security-admission v0.29.9/go.mod h1:e/hEPCPpwE2j8PohwrZliNfst50dxQq5Hyh6eCnZRAw= +k8s.io/sample-apiserver v0.29.9 h1:NruCyjLPOajut6TuRBjWPl4hjnzmgCic5UdYbyBXlBU= +k8s.io/sample-apiserver v0.29.9/go.mod h1:cy74Ju2TfeIaxJLyyd+fsLQ7kkRbV0c23TAof01wXCM= k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= @@ -1472,10 +1368,10 @@ modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 h1:trsWhjU5jZrx6UvFu4WzQDrN7Pga4a7Qg+zcfcj64PA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2/go.mod h1:+qG7ISXqCDVVcyO8hLn12AKVYYUjM7ftlqsqmrhMZE0= -sigs.k8s.io/controller-runtime v0.15.3 h1:L+t5heIaI3zeejoIyyvLQs5vTVu/67IU2FfisVzFlBc= -sigs.k8s.io/controller-runtime v0.15.3/go.mod h1:kp4jckA4vTx281S/0Yk2LFEEQe67mjg+ev/yknv47Ds= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= +sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= +sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.22.0 h1:z/+yr/azoOfzsfooqRsPw1wjJlqT/ukXP0ShkHwNlsI= @@ -1486,8 +1382,10 @@ sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKU sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/network-policy-api v0.1.5 h1:xyS7VAaM9EfyB428oFk7WjWaCK6B129i+ILUF4C8l6E= +sigs.k8s.io/network-policy-api v0.1.5/go.mod h1:D7Nkr43VLNd7iYryemnj8qf0N/WjBzTZDxYA+g4u1/Y= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/hack/postrelease/golang/README.md b/hack/postrelease/golang/README.md new file mode 100644 index 00000000000..45401f128fe --- /dev/null +++ b/hack/postrelease/golang/README.md @@ -0,0 +1,35 @@ +# Open-source postrelease tests! + +## How to run + +You can use `go test`` to run the tests: + +``` +$ go test -v ./... +``` + +Or, for slightly nicer/cleaner progress output, `gotestsum`: + +``` +$ gotestsum --format dots-v2 ./... +``` + +## How to lint + +This package has been linted with [revive](https://github.com/mgechev/revive); if you're +adding new tests or functionality, please consider doing the same. + +## Structure + +``` +pkg/* # All the various utility functions +tests/ # The actual test suites + oss/ # Test suites for Calico OSS specifically + openstack/ # Openstack-related tests + images/ # Tests to validate container images were published + helm/ # Fetches and validates the helm chart + github/* # Github-related validations for various repositories +``` + +In future, more test suites will be added to `tests`; for example, maybe `tests/operator` for +operator-related validations. diff --git a/hack/postrelease/golang/go.mod b/hack/postrelease/golang/go.mod new file mode 100644 index 00000000000..8dd0f4b182d --- /dev/null +++ b/hack/postrelease/golang/go.mod @@ -0,0 +1,53 @@ +module github.com/projectcalico/calico/hack/postrelease/golang + +go 1.22.3 + +require ( + github.com/cheggaaa/pb/v3 v3.1.5 + github.com/docker/docker v25.0.6+incompatible + github.com/google/go-github/v63 v63.0.0 + github.com/integralist/go-findroot v0.0.0-20160518114804-ac90681525dc + github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/regclient/regclient v0.7.1 + github.com/stretchr/testify v1.9.0 + gopkg.in/yaml.v3 v3.0.1 + helm.sh/helm/v3 v3.15.4 +) + +require ( + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/VividCortex/ewma v1.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/ulikunitz/xz v0.5.12 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect + golang.org/x/sys v0.24.0 // indirect + gotest.tools/v3 v3.5.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/hack/postrelease/golang/go.sum b/hack/postrelease/golang/go.sum new file mode 100644 index 00000000000..b84d3ca8db3 --- /dev/null +++ b/hack/postrelease/golang/go.sum @@ -0,0 +1,171 @@ +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= +github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk= +github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= +github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE= +github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/integralist/go-findroot v0.0.0-20160518114804-ac90681525dc h1:4IZpk3M4m6ypx0IlRoEyEyY1gAdicWLMQ0NcG/gBnnA= +github.com/integralist/go-findroot v0.0.0-20160518114804-ac90681525dc/go.mod h1:UlaC6ndby46IJz9m/03cZPKKkR9ykeIVBBDE3UDBdJk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/olareg/olareg v0.1.0 h1:1dXBOgPrig5N7zoXyIZVQqU0QBo6sD9pbL6UYjY75CA= +github.com/olareg/olareg v0.1.0/go.mod h1:RBuU7JW7SoIIxZKzLRhq8sVtQeAHzCAtRrXEBx2KlM4= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= +github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/regclient/regclient v0.7.1 h1:qEsJrTmZd98fZKjueAbrZCSNGU+ifnr6xjlSAs3WOPs= +github.com/regclient/regclient v0.7.1/go.mod h1:+w/BFtJuw0h0nzIw/z2+1FuA2/dVXBzDq4rYmziJpMc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +helm.sh/helm/v3 v3.15.4 h1:UFHd6oZ1IN3FsUZ7XNhOQDyQ2QYknBNWRHH57e9cbHY= +helm.sh/helm/v3 v3.15.4/go.mod h1:phOwlxqGSgppCY/ysWBNRhG3MtnpsttOzxaTK+Mt40E= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/hack/postrelease/golang/pkg/container/container.go b/hack/postrelease/golang/pkg/container/container.go new file mode 100644 index 00000000000..681c289fafa --- /dev/null +++ b/hack/postrelease/golang/pkg/container/container.go @@ -0,0 +1,35 @@ +// Package container contains universal functionality for container images +package container + +import ( + "fmt" + "strings" +) + +// Image is an object to represent a Docker/OCI image with tag on a specific docker host +type Image struct { + HostName string + Name string + Tag string +} + +// FullPath will combine the HostName, Name, and Tag into a full URI for the container +func (i Image) FullPath() string { + var registryPath string + + if strings.HasSuffix(i.HostName, "gcr.io") { + registryPath = "projectcalico-org" + } else { + registryPath = "calico" + } + + if strings.Contains(i.Name, "/") { + return fmt.Sprintf("%s/%s", i.HostName, i.Name) + } + return fmt.Sprintf("%s/%s/%s", i.HostName, registryPath, i.Name) +} + +// FullPathWithTag returns the full pathname of the specified image including the tag +func (i Image) FullPathWithTag() string { + return fmt.Sprintf("%s:%s", i.FullPath(), i.Tag) +} diff --git a/hack/postrelease/golang/pkg/github/github.go b/hack/postrelease/golang/pkg/github/github.go new file mode 100644 index 00000000000..e506cf7f38e --- /dev/null +++ b/hack/postrelease/golang/pkg/github/github.go @@ -0,0 +1,68 @@ +// Package github contains functionality for interacting with the Github API +package github + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/google/go-github/v63/github" +) + +var githubToken = os.Getenv("GITHUB_TOKEN") + +// GetGithubClient returns an instance of github.Client using a token from the environment. +func GetGithubClient() *github.Client { + ghClient := github.NewClient(nil) + if githubToken != "" { + ghClient = ghClient.WithAuthToken(githubToken) + } + return ghClient +} + +// GetProjectReleaseByTag fetches the release object for `releaseTag` from project `project` +func GetProjectReleaseByTag(project, releaseTag string) (*github.RepositoryRelease, error) { + names := strings.Split(project, "/") + orgName := names[0] + projectName := names[1] + + ghClient := GetGithubClient() + + release, _, err := ghClient.Repositories.GetReleaseByTag(context.Background(), orgName, projectName, releaseTag) + if err != nil { + return nil, fmt.Errorf("could not get release %s from github project %s: %w", releaseTag, project, err) + } + + return release, nil +} + +// GetProjectReleaseArtifacts gets a list of release asset objects from a given release of a project +func GetProjectReleaseArtifacts(project, releaseTag string) ([]*github.ReleaseAsset, error) { + var assets []*github.ReleaseAsset + + release, err := GetProjectReleaseByTag(project, releaseTag) + if err != nil { + return nil, fmt.Errorf("could not get artifacts for release %s from github project %s: %w", releaseTag, project, err) + } + + assets = append(assets, release.Assets...) + + return assets, nil +} + +// GetProjectReleaseArtifactNames gets a list of asset filenames for a given release of a project +func GetProjectReleaseArtifactNames(project, releaseTag string) ([]string, error) { + var assetNames []string + + assets, err := GetProjectReleaseArtifacts(project, releaseTag) + if err != nil { + return nil, fmt.Errorf("could not get names for artifacts for release %s from github project %s: %w", releaseTag, project, err) + } + + for _, assetObj := range assets { + assetNames = append(assetNames, assetObj.GetName()) + } + + return assetNames, nil +} diff --git a/hack/postrelease/golang/pkg/helm/helm.go b/hack/postrelease/golang/pkg/helm/helm.go new file mode 100644 index 00000000000..f925cae593a --- /dev/null +++ b/hack/postrelease/golang/pkg/helm/helm.go @@ -0,0 +1,132 @@ +// Package helm contains functionality and data structures for interacting with helm charts +package helm + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + "time" + + "gopkg.in/yaml.v3" + "helm.sh/helm/v3/pkg/chart/loader" +) + +// Index represents a helm index yaml file and all of its entries +type Index struct { + APIVersion string `yaml:"apiVersion"` + Entries struct { + TigeraOperator []struct { + APIVersion string `yaml:"apiVersion"` + AppVersion string `yaml:"appVersion"` + Created time.Time `yaml:"created"` + Description string `yaml:"description"` + Digest string `yaml:"digest"` + Home string `yaml:"home"` + Icon string `yaml:"icon"` + Name string `yaml:"name"` + Sources []string `yaml:"sources"` + Urls []string `yaml:"urls"` + Version string `yaml:"version"` + } `yaml:"tigera-operator"` + } `yaml:"entries"` +} + +// CheckVersionIsPublished ensures that this Index contains the version specified +func (hi Index) CheckVersionIsPublished(version string) bool { + for _, operator := range hi.Entries.TigeraOperator { + if operator.AppVersion == version { + return true + } + } + return false +} + +var ( + helmChartURL = "https://projectcalico.docs.tigera.io/charts/index.yaml" + operatorBundleURL = "https://github.com/projectcalico/calico/releases/download/%s/tigera-operator-%s.tgz" +) + +// GetIndex fetches and returns the projectcalico helm chart index +func GetIndex() (Index, error) { + chartIndex := Index{} + + buf := &bytes.Buffer{} + + resp, err := http.Get(helmChartURL) + if err != nil { + return chartIndex, fmt.Errorf("could not fetch helm chart: %w", err) + } + defer resp.Body.Close() + + _, err = io.Copy(buf, resp.Body) + if err != nil { + panic(err) + } + + err = yaml.Unmarshal(buf.Bytes(), &chartIndex) + if err != nil { + log.Fatalf("error: %v", err) + } + + return chartIndex, nil +} + +// LoadArchiveForVersion downloads, unpacks, and loads a helm chart from an operator tarball +func LoadArchiveForVersion(version string) error { + targetOperatorURL := fmt.Sprintf(operatorBundleURL, version, version) + + resp, err := http.Get(targetOperatorURL) + if err != nil { + return fmt.Errorf("could not fetch helm chart: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("failed to fetch helm archive: server returned %s", resp.Status) + } + + tempDirPath, err := os.MkdirTemp("", "*-tigera-operator-helm") + if err != nil { + return fmt.Errorf("could not create temp dir: %w", err) + } + defer os.RemoveAll(tempDirPath) + + gzipReader, err := gzip.NewReader(resp.Body) + if err != nil { + panic(err) + } + + tarReader := tar.NewReader(gzipReader) + + for { + header, err := tarReader.Next() + if err == io.EOF { + break // End of archive + } + if err != nil { + log.Fatal(err) + } + fullPath := filepath.Join(tempDirPath, header.Name) + if err := os.MkdirAll(filepath.Dir(fullPath), 0o700); err != nil { + return err + } + outfile, err := os.Create(fullPath) + if err != nil { + return err + } + io.Copy(outfile, tarReader) + } + + _, err = loader.LoadDir(filepath.Join(tempDirPath, "tigera-operator")) + if err != nil { + return err + } + + return nil +} diff --git a/hack/postrelease/golang/pkg/openstack/openstack.go b/hack/postrelease/golang/pkg/openstack/openstack.go new file mode 100644 index 00000000000..310fcb0d00b --- /dev/null +++ b/hack/postrelease/golang/pkg/openstack/openstack.go @@ -0,0 +1,189 @@ +// Package openstack contains functionality for calculating and validating openstack package releases +package openstack + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "strings" +) + +// PackageRevision represents a package with all its various permutations +type PackageRevision struct { + BaseURL string + Component string + Version string + OSVersion string + Arch string + Template *template.Template +} + +func (pr PackageRevision) toURL() (string, error) { + buf := &bytes.Buffer{} + err := pr.Template.Execute(buf, pr) + return buf.String(), err +} + +// Head fetches and returns the HTTP HEAD response for a given PackageRevision +func (pr PackageRevision) Head() (*http.Response, error) { + url, err := pr.toURL() + if err != nil { + panic(fmt.Errorf("could not generate url: %w", err)) + } + + response, err := http.Head(url) + if err != nil { + return response, fmt.Errorf("could not fetch url: %w", err) + } + return response, err +} + +// rhelComponent represents a component which we publish for RHEL +type rhelComponent struct { + Name string + Native bool +} + +// ubuntuComponent represents a component which we publish for Ubuntu +type ubuntuComponent struct { + Name string + ComponentName string +} + +var urlTemplates = map[string]map[string]string{ + "ubuntu": { + "felix": "http://ppa.launchpad.net/project-calico/%s/ubuntu/pool/main/f/felix", + "networking-calico": "http://ppa.launchpad.net/project-calico/%s/ubuntu/pool/main/n/networking-calico", + }, + "rpm": { + "x86_64": "http://binaries.projectcalico.org/rpm/%s/x86_64", + "noarch": "http://binaries.projectcalico.org/rpm/%s/noarch", + }, +} + +var dnsmasqVersion = "2.79_calico1-2" + +var ( + ubuntuTemplate = `{{ .BaseURL }}/{{ .Component }}_{{ .Version }}-{{ .OSVersion }}_{{ .Arch }}.deb` + rhelTemplate = `{{ .BaseURL }}/{{ .Component }}-{{ .Version }}.{{ .OSVersion }}.{{ .Arch }}.rpm` + dnsmasqTemplate = `{{ .BaseURL }}/{{ .Component }}-{{ .Version }}.{{ .OSVersion }}.2.{{ .Arch }}.rpm` +) + +var rhelVersions = [...]string{ + "el7", +} + +var rpmArches = [...]string{ + "x86_64", +} + +var ubuntuVersions = [...]string{ + "focal", + "jammy", +} + +var rpmComponents = [...]rhelComponent{ + // 'Native' components built for their specific architecture + {Name: "calico-common", Native: true}, + {Name: "calico-felix", Native: true}, + {Name: "felix-debuginfo", Native: true}, + + // dnsmasq-related components + {Name: "dnsmasq", Native: true}, + {Name: "dnsmasq-debuginfo", Native: true}, + {Name: "dnsmasq-utils", Native: true}, + + // Non-native components (i.e. 'noarch') + {Name: "calico-compute", Native: false}, + {Name: "calico-control", Native: false}, + {Name: "calico-dhcp-agent", Native: false}, + {Name: "networking-calico", Native: false}, +} + +var ubuntuComponents = [...]ubuntuComponent{ + // Components filed under 'networking-calico' on the PPA + {Name: "calico-compute", ComponentName: "networking-calico"}, + {Name: "calico-control", ComponentName: "networking-calico"}, + {Name: "calico-dhcp-agent", ComponentName: "networking-calico"}, + {Name: "networking-calico", ComponentName: "networking-calico"}, + // Components filed under 'felix' on the PPA + {Name: "calico-common", ComponentName: "felix"}, + {Name: "calico-felix", ComponentName: "felix"}, +} + +// GetPackages calculates and returns the expected packages for a given calico release +func GetPackages(releaseStream string) map[string][]PackageRevision { + ppaVersion := strings.Replace(releaseStream[0:5], "v", "calico-", 1) + calicoComponentVersion := strings.Replace(releaseStream, "v", "", 1) + + ubuntuTmpl, err := template.New("ubuntuTemplate").Parse(ubuntuTemplate) + if err != nil { + panic(err) + } + rhelTmpl, err := template.New("rhelTemplate").Parse(rhelTemplate) + if err != nil { + panic(err) + } + + dnsmasqTmpl, err := template.New("dnsmasqTemplate").Parse(dnsmasqTemplate) + if err != nil { + panic(err) + } + + packageList := make(map[string][]PackageRevision, 0) + + for _, rpmArch := range rpmArches { + for _, rhelVersion := range rhelVersions { + for _, rpmComponent := range rpmComponents { + var arch string + var template *template.Template + var componentVersion string + if rpmComponent.Native { + arch = rpmArch + } else { + arch = "noarch" + } + if strings.HasPrefix(rpmComponent.Name, "dnsmasq") { + componentVersion = dnsmasqVersion + template = dnsmasqTmpl + } else { + componentVersion = calicoComponentVersion + "-1" + template = rhelTmpl + } + component := PackageRevision{ + BaseURL: fmt.Sprintf(urlTemplates["rpm"][arch], ppaVersion), + Component: rpmComponent.Name, + Version: componentVersion, + OSVersion: rhelVersion, + Arch: arch, + Template: template, + } + packageList["rhel"] = append(packageList["rhel"], component) + } + } + } + + for _, ubuntuComponent := range ubuntuComponents { + var arch string + if ubuntuComponent.Name == "calico-felix" { + arch = "amd64" + } else { + arch = "all" + } + + for _, ubuntuVersion := range ubuntuVersions { + component := PackageRevision{ + BaseURL: fmt.Sprintf(urlTemplates["ubuntu"][ubuntuComponent.ComponentName], ppaVersion), + Component: ubuntuComponent.Name, + Version: calicoComponentVersion, + OSVersion: ubuntuVersion, + Arch: arch, + Template: ubuntuTmpl, + } + packageList["ubuntu"] = append(packageList["ubuntu"], component) + } + } + + return packageList +} diff --git a/hack/postrelease/golang/pkg/registry/registry.go b/hack/postrelease/golang/pkg/registry/registry.go new file mode 100644 index 00000000000..28d9513d47d --- /dev/null +++ b/hack/postrelease/golang/pkg/registry/registry.go @@ -0,0 +1,84 @@ +// Package registry contains helper functionality for interacting with docker registries +package registry + +import ( + "context" + "fmt" + "slices" + "sync" + + "github.com/patrickmn/go-cache" + "github.com/regclient/regclient" + "github.com/regclient/regclient/types/ref" + + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/container" +) + +// Checker manages references to registries and caches API results +type Checker struct { + Cache *cache.Cache + Lock *sync.Mutex + Context context.Context + Registry regclient.RegClient +} + +// New creates and configures a RegistryChecker instance +func New() (Checker, error) { + reg := Checker{} + reg.Cache = cache.New(cache.NoExpiration, cache.NoExpiration) + reg.Context = context.Background() + reg.Registry = *regclient.New() + + lock := sync.Mutex{} + reg.Lock = &lock + + reg.Cache.Add("CacheHit", 0, cache.NoExpiration) + reg.Cache.Add("CacheMiss", 0, cache.NoExpiration) + + return reg, nil +} + +func (reg Checker) fetchImageTagInfo(ImageName string) ([]string, error) { + imageRef, err := ref.New(ImageName) + if err != nil { + return nil, fmt.Errorf("failed to create ref: %w", err) + } + // defer reg.Registry.Close(reg.Context, imageRef) + + // get a manifest (or call other regclient methods) + TagList, err := reg.Registry.TagList(reg.Context, imageRef) + if err != nil { + return nil, fmt.Errorf("failed to get manifest: %w", err) + } + + return TagList.Tags, nil +} + +// CheckImageTagExists validates that the image tag exists, fetching and caching image data if necessary +func (reg Checker) CheckImageTagExists(ContainerImage container.Image) error { + reg.Lock.Lock() + var TagList []string + + ImagePath := ContainerImage.FullPath() + + if x, found := reg.Cache.Get(ImagePath); found { + reg.Cache.IncrementInt("CacheHit", 1) + TagList = x.([]string) + } else { + reg.Cache.IncrementInt("CacheMiss", 1) + x, err := reg.fetchImageTagInfo(ImagePath) + if err != nil { + errmsg := fmt.Sprintf("failed to fetch image tag info for %s", ImagePath) + return fmt.Errorf("%s: %w", errmsg, err) + } + TagList = x + reg.Cache.Add(ImagePath, TagList, cache.NoExpiration) + } + reg.Lock.Unlock() + + if slices.Contains(TagList, ContainerImage.Tag) { + return nil + } + errmsg := fmt.Sprintf("tag %s not found in tag list for %s", ContainerImage.Tag, ImagePath) + return fmt.Errorf(errmsg) +} diff --git a/hack/postrelease/golang/pkg/utils/download.go b/hack/postrelease/golang/pkg/utils/download.go new file mode 100644 index 00000000000..13639712d5a --- /dev/null +++ b/hack/postrelease/golang/pkg/utils/download.go @@ -0,0 +1,127 @@ +// Package utils contains functions that don't have a place anywhere else +package utils + +import ( + "errors" + "fmt" + "io" + "net/http" + "os" + "strconv" + + "github.com/cheggaaa/pb/v3" +) + +// WriteCounter is a Writer which provides a progress bar (instead +// of writing data! Use an `io.TeeReader` or similar.) +type WriteCounter struct { + Total uint64 + DownloadSize uint64 + ProgressBar *pb.ProgressBar +} + +// PrintProgress prints the progress of a file write +func (wc WriteCounter) PrintProgress() { + // Clear the line by using a character return to go back to the start and remove + // the remaining characters by filling it with spaces + // fmt.Printf("\r%s", strings.Repeat(" ", 50)) + + // Return again and print current status of download + // We use the humanize package to print the bytes in a meaningful way (e.g. 10 MB) + // fmt.Printf("\rDownloading... %s/%s complete", humanize.Bytes(wc.Total), humanize.Bytes(wc.DownloadSize)) + + wc.ProgressBar.Add64(int64(wc.Total)) + wc.ProgressBar.Increment() +} + +// Counts "written" bytes and updates the progress counter +func (wc *WriteCounter) Write(p []byte) (int, error) { + n := len(p) + wc.Total = uint64(n) + wc.PrintProgress() + return n, nil +} + +// MaybeDownloadFile downloads or resumes a download +func MaybeDownloadFile(url, filepath string) error { + if stat, err := os.Stat(filepath + ".tmp"); err == nil { + resp, err := http.Head(url) + if err != nil { + return err + } + defer resp.Body.Close() + + // Size + size, _ := strconv.Atoi(resp.Header.Get("Content-Length")) + downloadSize := int64(size) + + if stat.Size() == downloadSize { + // We already have the file + return nil + } else if stat.Size() < downloadSize { + fmt.Printf("Need to resume from %v\n", stat.Size()) + } + } else if errors.Is(err, os.ErrNotExist) { + // path/to/whatever does *not* exist + return DownloadFile(url, filepath) + } else { + return fmt.Errorf("could not maybe download file: %w", err) + } + + return nil +} + +// DownloadFile downloads a url to a filepath via a temporary file +func DownloadFile(url, filepath string) error { + // Create the file with .tmp extension, so that we won't overwrite a + // file until it's downloaded fully + out, err := os.Create(filepath + ".tmp") + if err != nil { + return err + } + defer out.Close() + + // Get the data + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + // Size + size, _ := strconv.Atoi(resp.Header.Get("Content-Length")) + downloadSize := uint64(size) + + tmpl := `{{string . "filename" }} {{ bar . }} {{speed . }} {{percent .}}` + + // Progress Bar + bar := pb.New64(int64(downloadSize)) + bar.SetMaxWidth(100) + bar.SetWriter(os.Stdout) + bar.Set(pb.Bytes, true) + bar.SetTemplateString(tmpl) + bar.Set("filename", filepath) + bar.Start() + defer bar.Finish() + + // Create our bytes counter and pass it to be used alongside our writer + counter := &WriteCounter{ + DownloadSize: downloadSize, + ProgressBar: bar, + } + _, err = io.Copy(out, io.TeeReader(resp.Body, counter)) + if err != nil { + return err + } + + // The progress use the same line so print a new line once it's finished downloading + // fmt.Println() + + // Rename the tmp file back to the original file + err = os.Rename(filepath+".tmp", filepath) + if err != nil { + return err + } + + return nil +} diff --git a/hack/postrelease/golang/pkg/variables/oss_defaults.go b/hack/postrelease/golang/pkg/variables/oss_defaults.go new file mode 100644 index 00000000000..47122f7f89f --- /dev/null +++ b/hack/postrelease/golang/pkg/variables/oss_defaults.go @@ -0,0 +1,38 @@ +// Package variables includes functionality for detecting and returning variables for OSS +package variables + +import ( + "os" + "path/filepath" + + "github.com/integralist/go-findroot/find" +) + +var ( + tigeraOperatorValuesPath = "charts/tigera-operator/values.yaml" + calicoValuesPath = "charts/calico/values.yaml" +) + +func getGitRoot() string { + root, err := find.Repo() + if err != nil { + panic(err) + } + return root.Path +} + +func filePathAtGitRoot(targetFile string) string { + gitRoot := getGitRoot() + return filepath.Join(gitRoot, targetFile) +} + +// GetOSSDefaults fetches and returns the default configuration variables for OSS Calico +func GetOSSDefaults() { + // var operatorValues map[string]interface{} + + file, err := os.Open(filePathAtGitRoot(tigeraOperatorValuesPath)) + if err != nil { + panic(err) + } + defer file.Close() +} diff --git a/hack/postrelease/golang/tests/operator/images/images_test.go b/hack/postrelease/golang/tests/operator/images/images_test.go new file mode 100644 index 00000000000..74c00c02452 --- /dev/null +++ b/hack/postrelease/golang/tests/operator/images/images_test.go @@ -0,0 +1,5 @@ +package images + +import "os" + +var operatorReleaseVersion = os.Getenv("OPERATOR_VERSION") diff --git a/hack/postrelease/golang/tests/oss/github/calico/github_calico_test.go b/hack/postrelease/golang/tests/oss/github/calico/github_calico_test.go new file mode 100644 index 00000000000..921ba290a93 --- /dev/null +++ b/hack/postrelease/golang/tests/oss/github/calico/github_calico_test.go @@ -0,0 +1,68 @@ +package oss + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/github" +) + +var ( + calicoReleaseTag = os.Getenv("CALICO_VERSION") + calicoProjectName = "projectcalico/calico" +) + +var expectedCalicoAssets = []string{ + "calico-windows-%s.zip", + "calicoctl-darwin-amd64", + "calicoctl-darwin-arm64", + "calicoctl-linux-amd64", + "calicoctl-linux-arm64", + "calicoctl-linux-ppc64le", + "calicoctl-linux-s390x", + "calicoctl-windows-amd64.exe", + "install-calico-windows.ps1", + "metadata.yaml", + "ocp.tgz", + "release-%s.tgz", + "SHA256SUMS", + "tigera-operator-%s.tgz", +} + +func TestMain(m *testing.M) { + failed := false + if calicoReleaseTag == "" { + fmt.Println("Missing CALICO_VERSION variable!") + failed = true + } + if failed { + fmt.Println("Please set the appropriate variables and then re-run the test suite") + os.Exit(2) + } + + v := m.Run() + os.Exit(v) +} + +func Test_CalicoGithubRelease(t *testing.T) { + _, err := github.GetProjectReleaseByTag(calicoProjectName, calicoReleaseTag) + assert.NoError(t, err) + + releaseArtifactNames, err := github.GetProjectReleaseArtifactNames(calicoProjectName, calicoReleaseTag) + assert.NoError(t, err) + + for _, desiredName := range expectedCalicoAssets { + if strings.Contains(desiredName, "%s") { + desiredName = fmt.Sprintf(desiredName, calicoReleaseTag) + } + testName := fmt.Sprintf("ReleaseAssetExists:%s", desiredName) + t.Run(testName, func(t *testing.T) { + t.Parallel() + assert.Contains(t, releaseArtifactNames, desiredName) + }) + } +} diff --git a/hack/postrelease/golang/tests/oss/github/flannel/github_flannel_test.go b/hack/postrelease/golang/tests/oss/github/flannel/github_flannel_test.go new file mode 100644 index 00000000000..38484641b46 --- /dev/null +++ b/hack/postrelease/golang/tests/oss/github/flannel/github_flannel_test.go @@ -0,0 +1,77 @@ +package oss + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/github" +) + +var ( + flannelProjectName = "coreos/flannel" + flannelReleaseTag = os.Getenv("FLANNEL_VERSION") +) + +var expectedFlannelAssets = []string{ + "flannel-%s-linux-amd64.tar.gz", + "flannel-%s-linux-arm.tar.gz", + "flannel-%s-linux-arm64.tar.gz", + "flannel-%s-linux-mips64le.tar.gz", + "flannel-%s-linux-ppc64le.tar.gz", + "flannel-%s-linux-s390x.tar.gz", + "flannel-%s-windows-amd64.tar.gz", + "flannel.tgz", + "flanneld-amd64", + "flanneld-arm", + "flanneld-arm64", + "flanneld-mips64le", + "flanneld-ppc64le", + "flanneld-s390x", + "flanneld-%s-amd64.docker", + "flanneld-%s-arm.docker", + "flanneld-%s-arm64.docker", + "flanneld-%s-mips64le.docker", + "flanneld-%s-ppc64le.docker", + "flanneld-%s-s390x.docker", + "flanneld.exe", + "kube-flannel-psp.yml", + "kube-flannel.yml", +} + +func TestMain(m *testing.M) { + failed := false + if flannelReleaseTag == "" { + fmt.Println("Missing FLANNEL_RELEASE variable!") + failed = true + } + if failed { + fmt.Println("Please set the appropriate variables and then re-run the test suite") + os.Exit(2) + } + + v := m.Run() + os.Exit(v) +} + +func Test_FlannelGithubRelease(t *testing.T) { + _, err := github.GetProjectReleaseByTag(flannelProjectName, flannelReleaseTag) + assert.NoError(t, err) + + releaseArtifactNames, err := github.GetProjectReleaseArtifactNames(flannelProjectName, flannelReleaseTag) + assert.NoError(t, err) + + for _, desiredName := range expectedFlannelAssets { + if strings.Contains(desiredName, "%s") { + desiredName = fmt.Sprintf(desiredName, flannelReleaseTag) + } + testName := fmt.Sprintf("ReleaseAssetExists:%s", desiredName) + t.Run(testName, func(t *testing.T) { + t.Parallel() + assert.Contains(t, releaseArtifactNames, desiredName) + }) + } +} diff --git a/hack/postrelease/golang/tests/oss/helm/helm_test.go b/hack/postrelease/golang/tests/oss/helm/helm_test.go new file mode 100644 index 00000000000..950e2360525 --- /dev/null +++ b/hack/postrelease/golang/tests/oss/helm/helm_test.go @@ -0,0 +1,44 @@ +package oss + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/helm" +) + +var calicoReleaseTag = os.Getenv("CALICO_VERSION") + +func TestMain(m *testing.M) { + failed := false + if calicoReleaseTag == "" { + fmt.Println("Missing CALICO_VERSION variable!") + failed = true + } + if failed { + fmt.Println("Please set the appropriate variables and then re-run the test suite") + os.Exit(2) + } + + v := m.Run() + os.Exit(v) +} + +func Test_ValidateHelmChart(t *testing.T) { + t.Parallel() + t.Run("HelmChartIsInIndex", func(t *testing.T) { + t.Parallel() + index, err := helm.GetIndex() + assert.NoError(t, err) + assert.True(t, index.CheckVersionIsPublished(calicoReleaseTag)) + }) + + t.Run("HelmChartCanBeLoaded", func(t *testing.T) { + t.Parallel() + err := helm.LoadArchiveForVersion(calicoReleaseTag) + assert.NoError(t, err) + }) +} diff --git a/hack/postrelease/golang/tests/oss/images/images_test.go b/hack/postrelease/golang/tests/oss/images/images_test.go new file mode 100644 index 00000000000..3c55b0a1205 --- /dev/null +++ b/hack/postrelease/golang/tests/oss/images/images_test.go @@ -0,0 +1,138 @@ +package oss + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/container" + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/registry" +) + +var ( + calicoReleaseTag = os.Getenv("CALICO_VERSION") + operatorReleaseVersion = os.Getenv("OPERATOR_VERSION") +) + +var dockerReleaseHosts = []string{ + "docker.io", + "quay.io", + "gcr.io", + "us.gcr.io", + "asia.gcr.io", + "eu.gcr.io", +} + +var expectedCalicoArches = []string{"amd64", "arm64", "s390x", "ppc64le"} + +var expectedCalicoImages = []string{ + "node", + "ctl", + "apiserver", + "typha", + "cni", + "kube-controllers", + // "upgrade", + "flannel-migration-controller", + "dikastes", + // "pilot-webhook", + "pod2daemon-flexvol", + "csi", + "key-cert-provisioner", +} + +var expectedWindowsImages = []string{ + "cni-windows", + "node-windows", +} + +var ( + regCheck registry.Checker + err error + imagesToTest []container.Image +) + +func TestMain(m *testing.M) { + failed := false + if calicoReleaseTag == "" { + fmt.Println("Missing CALICO_VERSION variable!") + failed = true + } + if operatorReleaseVersion == "" { + fmt.Println("Missing OPERATOR_RELEASE variable!") + failed = true + } + if failed { + fmt.Println("Please set the appropriate variables and then re-run the test suite") + os.Exit(2) + } + + v := m.Run() + os.Exit(v) +} + +func Test_ImagesPublished(t *testing.T) { + regCheck, err = registry.New() + if err != nil { + fmt.Println("I guess something failed") + panic(err) + } + imagesToTest = make([]container.Image, 0) + + containerImage := container.Image{ + Name: "tigera/operator", + Tag: operatorReleaseVersion, + HostName: "quay.io", + } + + imagesToTest = append(imagesToTest, containerImage) + for _, hostName := range dockerReleaseHosts { + for _, imageName := range expectedCalicoImages { + containerImage := container.Image{ + Name: imageName, + Tag: calicoReleaseTag, + HostName: hostName, + } + + imagesToTest = append(imagesToTest, containerImage) + + for _, archName := range expectedCalicoArches { + containerImage := container.Image{ + Name: imageName, + Tag: fmt.Sprintf("%s-%s", calicoReleaseTag, archName), + HostName: hostName, + } + imagesToTest = append(imagesToTest, containerImage) + } + } + for _, imageName := range expectedWindowsImages { + containerImage := container.Image{ + Name: imageName, + Tag: calicoReleaseTag, + HostName: hostName, + } + + imagesToTest = append(imagesToTest, containerImage) + } + } + for _, ci := range imagesToTest { + testName := fmt.Sprintf("ImageVerification:%s", ci.FullPathWithTag()) + t.Run(testName, func(t *testing.T) { + t.Parallel() + err := regCheck.CheckImageTagExists(ci) + assert.NoError(t, err) + }) + } + + t.Cleanup(func() { + var hitsCount int + var missesCount int + hits, _ := regCheck.Cache.Get("CacheHit") + misses, _ := regCheck.Cache.Get("CacheMiss") + hitsCount = hits.(int) + missesCount = misses.(int) + fmt.Printf("Got %v cache hits, %v misses (%v%% hit rate)\n", hitsCount, missesCount, hitsCount/(hitsCount+missesCount)*100) + }) +} diff --git a/hack/postrelease/golang/tests/oss/openstack/openstack_test.go b/hack/postrelease/golang/tests/oss/openstack/openstack_test.go new file mode 100644 index 00000000000..1baac1aaedb --- /dev/null +++ b/hack/postrelease/golang/tests/oss/openstack/openstack_test.go @@ -0,0 +1,43 @@ +package oss + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/projectcalico/calico/hack/postrelease/golang/pkg/openstack" +) + +var calicoReleaseTag = os.Getenv("CALICO_VERSION") + +func TestMain(m *testing.M) { + failed := false + if calicoReleaseTag == "" { + fmt.Println("Missing CALICO_VERSION variable!") + failed = true + } + if failed { + fmt.Println("Please set the appropriate variables and then re-run the test suite") + os.Exit(2) + } + + v := m.Run() + os.Exit(v) +} + +func Test_OpenStackPublished(t *testing.T) { + packageList := openstack.GetPackages(calicoReleaseTag) + for packagePlatform, packageObjList := range packageList { + for _, packageObj := range packageObjList { + testName := fmt.Sprintf("%s/%s/%s/%s %s", packagePlatform, packageObj.OSVersion, packageObj.Arch, packageObj.Component, packageObj.Version) + t.Run(testName, func(t *testing.T) { + t.Parallel() + resp, err := packageObj.Head() + assert.NoError(t, err) + assert.Equal(t, 200, resp.StatusCode, "blahblah") + }) + } + } +} diff --git a/hack/release/.gitignore b/hack/release/.gitignore deleted file mode 100644 index 70a914e7d6f..00000000000 --- a/hack/release/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.terraform/ -terraform.tfvars -.terraform.tfstate.lock.info -ssh_key -ssh_key.pub -terraform.tfstate -terraform.tfstate.backup -.terraform.lock.hcl -bin/ -.terraform.init diff --git a/hack/release/Makefile b/hack/release/Makefile deleted file mode 100644 index fd09fc05b0e..00000000000 --- a/hack/release/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -include ../../metadata.mk -include ../../lib.Makefile - -# We only ever release from the tip of a release branch. -GIT_BRANCH?=$(git rev-parse HEAD) - -# Build a release from the currently checked out commit. -# Uses SSH to run commands on the remote builder. -release: .vm.created - ./remote-execute.sh "cd calico && git fetch --tags && git checkout $(GIT_BRANCH)" - ./remote-execute.sh "cd calico && make release" - -git-fetch-remote: .vm.created - ./remote-execute.sh "cd calico && git fetch --tags && git checkout $(GIT_BRANCH)" - -update-versions-remote: .vm.created - ./remote-execute.sh "cd calico && make update-versions" - -generate-manifests-remote: .vm.created - ./remote-execute.sh "cd calico && make generate" - -commit-versions-remote: .vm.created - ./remote-execute.sh "cd calico && make commit-versions-manifests" - -build-release-remote: .vm.created - ./remote-execute.sh "cd calico && make release" - -# Expects that a release has already been created on the remote VM via the "release" target. -release-publish: .vm.created - ./remote-execute.sh "cd calico && make release-publish" - -# Create a VM using the given vars. -VAR_FILE ?= terraform.tfvars -apply: .vm.created -.vm.created: .terraform.init - ./bin/terraform apply --auto-approve -var-file=$(VAR_FILE) && touch $@ - -# Destroy the VM. -destroy: - ./bin/terraform destroy --auto-approve -var-file=$(VAR_FILE) - rm -f .vm.created - -# Tear down any existing VM, and create a new one. -rebuild: - $(MAKE) destroy apply - -# Initialize the terraform install. -.terraform.init: bin/terraform - ./bin/terraform init && touch $@ - -# Install the terraform binary. -bin/terraform: bin/terraform.zip - unzip bin/terraform.zip -d bin && touch $@ -bin/terraform.zip: - mkdir -p bin - curl -sSf -L --retry 5 -o $@ https://releases.hashicorp.com/terraform/1.1.7/terraform_1.1.7_linux_amd64.zip diff --git a/hack/release/cmd/main.go b/hack/release/cmd/main.go deleted file mode 100644 index 7d1bff0e0b4..00000000000 --- a/hack/release/cmd/main.go +++ /dev/null @@ -1,84 +0,0 @@ -package main - -import ( - "flag" - "io" - "os" - - "github.com/sirupsen/logrus" - lumberjack "gopkg.in/natefinch/lumberjack.v2" - - "github.com/projectcalico/calico/hack/release/pkg/builder" -) - -var create, publish, newBranch, meta bool -var dir string - -func init() { - flag.BoolVar(&create, "create", false, "Create a release from the current commit") - flag.BoolVar(&publish, "publish", false, "Publish the release built from the current tag") - flag.BoolVar(&newBranch, "new-branch", false, "Create a new release branch from master") - flag.BoolVar(&meta, "metadata", false, "Product release metadata") - - flag.StringVar(&dir, "dir", "./", "Directory to place build metadata in") - - flag.Parse() -} - -func main() { - // Create a releaseBuilder to use. - r := builder.NewReleaseBuilder(&builder.RealCommandRunner{}) - - if meta { - configureLogging("metadata.log") - err := r.BuildMetadata(dir) - if err != nil { - logrus.WithError(err).Error("Failed to produce release metadata") - os.Exit(1) - } - return - } - - if create { - configureLogging("release-build.log") - err := r.BuildRelease() - if err != nil { - logrus.WithError(err).Error("Failed to create Calico release") - os.Exit(1) - } - return - } - - if publish { - configureLogging("release-publish.log") - err := r.PublishRelease() - if err != nil { - logrus.WithError(err).Error("Failed to publish Calico release") - os.Exit(1) - } - return - } - - if newBranch { - configureLogging("cut-release-branch.log") - err := r.NewBranch() - if err != nil { - logrus.WithError(err).Error("Failed to create new release branch") - os.Exit(1) - } - return - } - - logrus.Fatalf("No command specified") -} - -func configureLogging(filename string) { - // Set up logging to both stdout as well as a file. - writers := []io.Writer{os.Stdout, &lumberjack.Logger{ - Filename: filename, - MaxSize: 100, - MaxAge: 30, - MaxBackups: 10, - }} - logrus.SetOutput(io.MultiWriter(writers...)) -} diff --git a/hack/release/generate-release-notes.py b/hack/release/generate-release-notes.py deleted file mode 100755 index 630eb03bb68..00000000000 --- a/hack/release/generate-release-notes.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python -import github -from github import Github # https://github.com/PyGithub/PyGithub -import os -import re -import io -import string -import datetime - -# First create a Github instance. Create a token through GitHub website - provide "repo" auth. -g = Github(os.environ.get('GITHUB_TOKEN')) - -# The milestone to generate notes for. -assert os.environ.get('VERSION') -VERSION=os.environ.get('VERSION') -MILESTONE="Calico %s" % VERSION -RELEASE_STREAM = ".".join(VERSION.split(".")[:2]) - -# The file where we'll store the release notes. -FILENAME="release-notes/%s-release-notes.md" % VERSION - -# Repositories we care about. Add repositories here to include them in release -# note generation. -REPOS = [ - "calico", - "bird", -] - -# Returns a dictionary where the keys are repositories, and the values are -# a list of issues in the repository which match the milestone and -# have a `release-note-required` label. -def issues_by_repo(): - all_issues = {} - org = g.get_organization("projectcalico") - for repo in org.get_repos(): - if not repo.name in REPOS: - continue - print("Processing repo %s/%s" % (org.login, repo.name)) - - # Find the milestone. This finds all open milestones. - milestones = repo.get_milestones() - for m in milestones: - if m.title == MILESTONE: - # Found the milestone in this repo - look for issues (but only - # ones that have been closed!) - # TODO: Assert that the PR has been merged somehow? - print(" found milestone %s" % m.title) - try: - label = repo.get_label("release-note-required") - except github.UnknownObjectException: - # Label doesn't exist, skip this repo. - break - issues = repo.get_issues(milestone=m, labels=[label], state="closed") - for i in issues: - all_issues.setdefault(repo.name, []).append(i) - return all_issues - -# Takes an issue and returns the appropriate release notes from that -# issue as a list. If it has a release-note section defined, that is used. -# If not, then it simply returns the title. -def extract_release_notes(issue): - # Look for a release note section in the body. - matches = re.findall(r'```release-note(.*?)```', issue.body, re.DOTALL) - if matches: - return [m.strip() for m in matches] - else: - print("WARNING: %s has no release-note section" % (issue.number)) - return [issue.title.strip()] - -if __name__ == "__main__": - # Get the list of issues. - all_issues = issues_by_repo() - - # Get date in the right format. - date = datetime.date.today().strftime("%d %b %Y") - - # Make the directory, if needed. - os.makedirs("release-notes") - - # Write release notes out to a file. - with io.open(FILENAME, "w", encoding='utf-8') as f: - f.write(u"%s\n\n" % date) - f.write(u"#### Headline feature 1\n\n") - f.write(u"#### Headline feature 2\n\n") - f.write(u"#### Bug fixes\n\n") - f.write(u"#### Other changes\n\n") - for repo, issues in all_issues.items(): - print("Writing notes for %s" % repo) - for i in issues: - for note in extract_release_notes(i): - f.write(" - %s [%s #%d](%s) (@%s)\n" % (note, repo, i.number, i.html_url, i.user.login)) - - print("") - print("Release notes written to " + FILENAME) - print("Please review for accuracy, and format appropriately before releasing.") diff --git a/hack/release/pkg/builder/builder_test.go b/hack/release/pkg/builder/builder_test.go deleted file mode 100644 index 806c6f5812f..00000000000 --- a/hack/release/pkg/builder/builder_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package builder - -import ( - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" -) - -var _ = DescribeTable("Release version determination tests", func(prev, expected string, expectErr bool) { - r := &ReleaseBuilder{} - out, err := r.determineReleaseVersion(prev) - if expectErr { - Expect(err).To(HaveOccurred()) - } else { - Expect(err).NotTo(HaveOccurred()) - } - Expect(out).To(Equal(expected)) -}, - - Entry("from a -0.dev tag", "v3.22.0-0.dev", "v3.22.0", false), - Entry("from a .0 patch release", "v3.22.0", "v3.22.1", false), - Entry("from a .10 patch release", "v3.22.10", "v3.22.11", false), - Entry("from a random string", "ahg5da29a", "", true), -) diff --git a/hack/release/remote-execute.sh b/hack/release/remote-execute.sh deleted file mode 100755 index f448f08e57a..00000000000 --- a/hack/release/remote-execute.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -# Get the SSH command, and use eval to remove the quotes from it. -ssh=$(./bin/terraform output connect_command) -ssh=$(eval echo $ssh) -eval "${ssh} -- '$1'" diff --git a/hack/release/terraform.tf b/hack/release/terraform.tf deleted file mode 100644 index 4b60be52b0e..00000000000 --- a/hack/release/terraform.tf +++ /dev/null @@ -1,145 +0,0 @@ -provider "google" { - project = var.google_project - region = var.google_region - zone = var.google_zone -} - -provider "google-beta" { - project = var.google_project - region = var.google_region - zone = var.google_zone -} - -resource "tls_private_key" "ssh" { - algorithm = "RSA" -} - -resource "google_compute_instance" "vm_instance" { - provider = google-beta - name = "${var.prefix}-calico-release-executor" - machine_type = var.machine_type - zone = var.google_zone - - service_account { - scopes = ["storage-ro", "cloud-platform", "compute-rw", "logging-write", "monitoring", "service-control", "service-management"] - } - - tags = ["calico-release"] - - metadata = { - ssh-keys = "ubuntu:${tls_private_key.ssh.public_key_openssh}" - } - - connection { - user = "ubuntu" - agent = false - private_key = tls_private_key.ssh.private_key_pem - host = self.network_interface.0.access_config.0.nat_ip - } - - boot_disk { - initialize_params { - image = var.image - type = var.disk_type - size = var.disk_size - } - } - - network_interface { - network = var.google_network - - access_config { - // This empty field requests an Ephemeral IP - } - } -} - -resource "null_resource" "configure_vm" { - connection { - user = "ubuntu" - agent = false - private_key = tls_private_key.ssh.private_key_pem - host = google_compute_instance.vm_instance.network_interface.0.access_config.0.nat_ip - } - - // Install the necessary environment for release. - provisioner "remote-exec" { - inline = [ - "sudo apt update", - "sudo apt install -y ca-certificates curl", - "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg", - "echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable' | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null", - "sudo apt update", - "sudo apt install -y docker-ce docker-ce-cli containerd.io", - "sudo apt install -y git make zip unzip", - "sudo usermod -aG docker ubuntu" - ] - } - - // Authenticate the docker daemon with GCR, dockerhub, and quay. - provisioner "file" { - source = var.gcr_auth_path - destination = "/tmp/gcr-credentials.json" - } - provisioner "remote-exec" { - inline = [ - "cat /tmp/gcr-credentials.json | docker login -u _json_key --password-stdin https://gcr.io", - "cat /tmp/gcr-credentials.json | docker login -u _json_key --password-stdin https://eu.gcr.io", - "cat /tmp/gcr-credentials.json | docker login -u _json_key --password-stdin https://asia.gcr.io", - "cat /tmp/gcr-credentials.json | docker login -u _json_key --password-stdin https://us.gcr.io", - "echo ${var.dockerhub_token} | docker login --username ${var.dockerhub_user} --password-stdin", - "echo ${var.quay_token} | docker login --username ${var.quay_user} --password-stdin quay.io", - ] - } - - // Set GITHUB_TOKEN in the environment. - provisioner "remote-exec" { - inline = [ - "sudo sh -c 'echo GITHUB_TOKEN=${var.github_token} >> /etc/environment'", - ] - } - - // Clone the Calico repository. We do this via HTTPS to clone initially, but change the remote to SSH - // to work around the fact that Terraform doesn't seem to forward SSH. - provisioner "remote-exec" { - inline = [ - "git clone https://github.com/projectcalico/calico /home/ubuntu/calico", - "cd /home/ubuntu/calico", - "git remote remove origin", - "git remote add origin git@github.com:projectcalico/calico.git", - "ssh-keyscan -H github.com >> ~/.ssh/known_hosts", - ] - } -} - -resource "local_file" "local_ssh_key" { - content = tls_private_key.ssh.private_key_pem - filename = "${path.root}/ssh_key" - - provisioner "local-exec" { - command = "chmod 600 ${path.root}/ssh_key" - } -} - -resource "local_file" "local_ssh_key_pub" { - content = tls_private_key.ssh.public_key_openssh - filename = "${path.root}/ssh_key.pub" - - provisioner "local-exec" { - command = "chmod 644 ${path.root}/ssh_key.pub" - } -} - -output "instance_ip" { - value = google_compute_instance.vm_instance.network_interface.0.access_config.0.nat_ip -} - -output "instance_ssh_key" { - value = "${abspath(path.root)}/ssh_key" - depends_on = [tls_private_key.ssh] -} - -output "connect_command" { - value = "ssh -A -i ${abspath(path.root)}/ssh_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ubuntu@${google_compute_instance.vm_instance.network_interface.0.access_config.0.nat_ip}" - depends_on = [tls_private_key.ssh] -} diff --git a/hack/release/variables.tf b/hack/release/variables.tf deleted file mode 100644 index b1a7fe482af..00000000000 --- a/hack/release/variables.tf +++ /dev/null @@ -1,68 +0,0 @@ -variable "google_project" { - type = string -} -variable "google_region" { - type = string -} -variable "google_zone" { - type = string -} -variable "prefix" { - type = string -} - -variable "machine_type" { - type = string - default = "n2-standard-32" -} - -variable "disk_size" { - type = number - default = 100 -} - -variable "disk_type" { - type = string - default = "pd-ssd" -} - -variable "image" { - type = string - description = "Select which image family to use." - default = "ubuntu-2004-lts" -} - -variable "google_network" { - type = string - default = "default" - description = "The name of the network to bring instances up on." -} - -variable "github_token" { - type = string -} - -variable "gcr_auth_path" { - type = string - description = "Path to docker authentication file for GCR." - validation { - condition = fileexists(pathexpand(var.gcr_auth_path)) - error_message = "Invalid docker auth file." - } -} - -variable "dockerhub_token" { - type = string -} - -variable "dockerhub_user" { - type = string -} - -variable "quay_token" { - type = string -} - -variable "quay_user" { - type = string -} diff --git a/hack/test/kind/kind-single.config b/hack/test/kind/kind-single.config index 6aec226b95a..5fea893778c 100644 --- a/hack/test/kind/kind-single.config +++ b/hack/test/kind/kind-single.config @@ -6,6 +6,7 @@ apiVersion: kind.x-k8s.io/v1alpha4 networking: disableDefaultCNI: true podSubnet: "192.168.0.0/16" + dnsSearch: [] nodes: # For libcalico-go tests, we only need a control plane node. - role: control-plane diff --git a/hack/test/kind/kind.config b/hack/test/kind/kind.config index 50e96f2c92e..fc72eab8434 100644 --- a/hack/test/kind/kind.config +++ b/hack/test/kind/kind.config @@ -5,6 +5,7 @@ networking: disableDefaultCNI: true podSubnet: "192.168.0.0/16,fd00:10:244::/64" ipFamily: dual + dnsSearch: [] nodes: - role: control-plane - role: worker diff --git a/kube-controllers/Makefile b/kube-controllers/Makefile index d2dcdf4e346..0cc9388f91f 100644 --- a/kube-controllers/Makefile +++ b/kube-controllers/Makefile @@ -75,7 +75,7 @@ $(BINDIR)/check-status-linux-$(ARCH): $(SRC_FILES) $(call build_binary, ./cmd/check-status, $@) $(BINDIR)/kubectl-$(ARCH): - curl -sSf -L --retry 5 -o $@ https://storage.googleapis.com/kubernetes-release/release/$(K8S_VERSION)/bin/linux/$(ARCH)/kubectl + curl -sSf -L --retry 5 -o $@ https://dl.k8s.io/release/$(K8S_VERSION)/bin/linux/$(ARCH)/kubectl chmod +x $@ ############################################################################### diff --git a/kube-controllers/cmd/kube-controllers/main.go b/kube-controllers/cmd/kube-controllers/main.go index 68ee5fa0673..54c2ecb20ee 100644 --- a/kube-controllers/cmd/kube-controllers/main.go +++ b/kube-controllers/cmd/kube-controllers/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,10 +24,6 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/promhttp" - - "github.com/projectcalico/calico/libcalico-go/lib/debugserver" - "github.com/projectcalico/calico/libcalico-go/lib/winutils" - log "github.com/sirupsen/logrus" "go.etcd.io/etcd/client/pkg/v3/srv" "go.etcd.io/etcd/client/pkg/v3/transport" @@ -38,10 +34,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" - client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" - "github.com/projectcalico/calico/libcalico-go/lib/logutils" - "github.com/projectcalico/calico/crypto/pkg/tls" "github.com/projectcalico/calico/kube-controllers/pkg/config" "github.com/projectcalico/calico/kube-controllers/pkg/controllers/controller" @@ -52,6 +44,11 @@ import ( "github.com/projectcalico/calico/kube-controllers/pkg/controllers/pod" "github.com/projectcalico/calico/kube-controllers/pkg/controllers/serviceaccount" "github.com/projectcalico/calico/kube-controllers/pkg/status" + "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" + client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/debugserver" + "github.com/projectcalico/calico/libcalico-go/lib/logutils" + "github.com/projectcalico/calico/libcalico-go/lib/winutils" ) // VERSION is filled out during the build process (using git describe output) @@ -84,11 +81,8 @@ func main() { os.Exit(0) } - // Configure log formatting. - log.SetFormatter(&logutils.Formatter{}) - - // Install a hook that adds file/line no information. - log.AddHook(&logutils.ContextHook{}) + // Set up logging formatting. + logutils.ConfigureFormatter("kube-controllers") // Attempt to load configuration. cfg := new(config.Config) diff --git a/kube-controllers/pkg/controllers/networkpolicy/policy_controller.go b/kube-controllers/pkg/controllers/networkpolicy/policy_controller.go index 940c221dfa8..d92ad1ce91a 100644 --- a/kube-controllers/pkg/controllers/networkpolicy/policy_controller.go +++ b/kube-controllers/pkg/controllers/networkpolicy/policy_controller.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017, 2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,9 +29,9 @@ import ( api "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/calico/kube-controllers/pkg/converter" - kdd "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" networkingv1 "k8s.io/api/networking/v1" @@ -72,7 +72,7 @@ func NewPolicyController(ctx context.Context, clientset *kubernetes.Clientset, c // Filter in only objects that are written by policy controller. m := make(map[string]interface{}) for _, policy := range calicoPolicies.Items { - if strings.HasPrefix(policy.Name, kdd.K8sNetworkPolicyNamePrefix) { + if strings.HasPrefix(policy.Name, names.K8sNetworkPolicyNamePrefix) { // Update the network policy's ObjectMeta so that it simply contains the name and namespace. // There is other metadata that we might receive (like resource version) that we don't want to // compare in the cache. diff --git a/kube-controllers/pkg/controllers/node/controller.go b/kube-controllers/pkg/controllers/node/controller.go index 68170c2c991..a1135dacd3c 100644 --- a/kube-controllers/pkg/controllers/node/controller.go +++ b/kube-controllers/pkg/controllers/node/controller.go @@ -40,9 +40,7 @@ const ( hepCreatedLabelValue = "calico-kube-controllers" ) -var ( - retrySleepTime = 100 * time.Millisecond -) +var retrySleepTime = 100 * time.Millisecond // NodeController implements the Controller interface. It is responsible for monitoring // kubernetes nodes and responding to delete events by removing them from the Calico datastore. @@ -67,7 +65,8 @@ func NewNodeController(ctx context.Context, k8sClientset *kubernetes.Clientset, calicoClient client.Interface, cfg config.NodeControllerConfig, - nodeInformer, podInformer cache.SharedIndexInformer) controller.Controller { + nodeInformer, podInformer cache.SharedIndexInformer, +) controller.Controller { nc := &NodeController{ ctx: ctx, calicoClient: calicoClient, @@ -102,7 +101,8 @@ func NewNodeController(ctx context.Context, for _, f := range nodeDeletionFuncs { f() } - }} + }, + } // Create the Auto HostEndpoint sub-controller and register it to receive data. // We always launch this controller, even if auto-HEPs are disabled, since the controller diff --git a/kube-controllers/pkg/controllers/node/fake_client.go b/kube-controllers/pkg/controllers/node/fake_client.go index b5b6e344839..760502d6f37 100644 --- a/kube-controllers/pkg/controllers/node/fake_client.go +++ b/kube-controllers/pkg/controllers/node/fake_client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -50,6 +50,11 @@ type FakeCalicoClient struct { ipamClient ipam.Interface } +// Tiers returns an interface for managing tier resources. +func (f *FakeCalicoClient) Tiers() clientv3.TierInterface { + panic("not implemented") // TODO: Implement +} + func (f *FakeCalicoClient) Backend() bapi.Client { return nil } diff --git a/kube-controllers/pkg/controllers/node/node_controller_fv_test.go b/kube-controllers/pkg/controllers/node/node_controller_fv_test.go index 5098f9c1512..73729a61625 100644 --- a/kube-controllers/pkg/controllers/node/node_controller_fv_test.go +++ b/kube-controllers/pkg/controllers/node/node_controller_fv_test.go @@ -881,7 +881,7 @@ func expectLabels(c client.Interface, labels map[string]string, node string) err if !reflect.DeepEqual(cn.Labels, labels) { s := fmt.Sprintf("Labels do not match.\n\nExpected: %#v\n Actual: %#v\n", labels, cn.Labels) logrus.Warn(s) - return fmt.Errorf(s) + return fmt.Errorf("%s", s) } return nil } diff --git a/kube-controllers/pkg/controllers/node/node_deleter.go b/kube-controllers/pkg/controllers/node/node_deleter.go index a89e0945d94..14cf934281e 100644 --- a/kube-controllers/pkg/controllers/node/node_deleter.go +++ b/kube-controllers/pkg/controllers/node/node_deleter.go @@ -23,6 +23,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/util/workqueue" + bapi "github.com/projectcalico/calico/libcalico-go/lib/backend/api" client "github.com/projectcalico/calico/libcalico-go/lib/clientv3" cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" "github.com/projectcalico/calico/libcalico-go/lib/options" @@ -31,29 +32,49 @@ import ( // NewNodeDeletionController creates a new controller responsible for garbage collection Calico node objects // in etcd mode when their corresponding Kubernetes node is deleted. func NewNodeDeletionController(client client.Interface, cs *kubernetes.Clientset) *nodeDeleter { - return &nodeDeleter{ + d := &nodeDeleter{ clientset: cs, client: client, rl: workqueue.DefaultControllerRateLimiter(), + syncChan: make(chan struct{}), } + go d.run() + return d } type nodeDeleter struct { rl workqueue.RateLimiter clientset *kubernetes.Clientset client client.Interface + syncChan chan struct{} } func (c *nodeDeleter) RegisterWith(f *DataFeed) { - // No-op - we only care about Kubernetes node deletion events. + // We use status updates to do a "start of day" sync. This controller doens't + // actually use the syncer feed, but we do key off syncer updates at start of day to + // trigger an initial sync. This helps catch scenarios where nodes may have been deleted + // while the controller was not running / being rescheduled. + f.RegisterForSyncStatus(c.onStatusUpdate) } func (c *nodeDeleter) OnKubernetesNodeDeleted() { // When a Kubernetes node is deleted, trigger a sync. log.Debug("Kubernetes node deletion event") - err := c.deleteStaleNodes() - if err != nil { - log.WithError(err).Warn("Error deleting any stale nodes") + c.syncChan <- struct{}{} +} + +func (c *nodeDeleter) onStatusUpdate(s bapi.SyncStatus) { + if s == bapi.InSync { + log.Info("Sync status is now in sync, checking for stale nodes") + c.syncChan <- struct{}{} + } +} + +func (c *nodeDeleter) run() { + for range c.syncChan { + if err := c.deleteStaleNodes(); err != nil { + log.WithError(err).Warn("Error deleting any stale nodes") + } } } diff --git a/kube-controllers/tests/testutils/node_controller_utils.go b/kube-controllers/tests/testutils/node_controller_utils.go index e3d41eaea01..b758c60124d 100644 --- a/kube-controllers/tests/testutils/node_controller_utils.go +++ b/kube-controllers/tests/testutils/node_controller_utils.go @@ -96,7 +96,7 @@ func ExpectNodeLabels(c client.Interface, labels map[string]string, node string) if !reflect.DeepEqual(cn.Labels, labels) { s := fmt.Sprintf("Labels do not match.\n\nExpected: %#v\n Actual: %#v\n", labels, cn.Labels) logrus.Warn(s) - return fmt.Errorf(s) + return fmt.Errorf("%s", s) } return nil } @@ -117,19 +117,19 @@ func ExpectHostendpoint(c client.Interface, hepName string, expectedLabels map[s if !reflect.DeepEqual(hep.Labels, expectedLabels) { s := fmt.Sprintf("labels do not match.\n\nExpected: %#v\n Actual: %#v\n", expectedLabels, hep.Labels) logrus.Warn(s) - return fmt.Errorf(s) + return fmt.Errorf("%s", s) } if !reflect.DeepEqual(hep.Spec.ExpectedIPs, expectedIPs) { s := fmt.Sprintf("expectedIPs do not match.\n\nExpected: %#v\n Actual: %#v\n", expectedIPs, hep.Spec.ExpectedIPs) logrus.Warn(s) - return fmt.Errorf(s) + return fmt.Errorf("%s", s) } if !reflect.DeepEqual(hep.Spec.Profiles, expectedProfiles) { s := fmt.Sprintf("profiles do not match.\n\nExpected: %#v\n Actual: %#v\n", expectedProfiles, hep.Spec.Profiles) logrus.Warn(s) - return fmt.Errorf(s) + return fmt.Errorf("%s", s) } return nil diff --git a/lib.Makefile b/lib.Makefile index 9b29f0c9bfa..45b41e01196 100644 --- a/lib.Makefile +++ b/lib.Makefile @@ -206,8 +206,8 @@ ifeq ($(GIT_USE_SSH),true) GIT_CONFIG_SSH ?= git config --global url."ssh://git@github.com/".insteadOf "https://github.com/"; endif -# Get version from git. -GIT_VERSION:=$(shell git describe --tags --dirty --always --abbrev=12) +# Get version from git. We allow setting this manually for the hashrelease process. +GIT_VERSION ?= $(shell git describe --tags --dirty --always --abbrev=12) # Figure out version information. To support builds from release tarballs, we default to # if this isn't a git checkout. @@ -1254,7 +1254,7 @@ $(KIND): $(KIND_DIR)/.kind-updated-$(KIND_VERSION) $(KUBECTL)-$(K8S_VERSION): mkdir -p $(KIND_DIR) - curl -L https://storage.googleapis.com/kubernetes-release/release/$(K8S_VERSION)/bin/linux/$(ARCH)/kubectl -o $@ + curl -fsSL --retry 5 https://dl.k8s.io/release/$(K8S_VERSION)/bin/linux/$(ARCH)/kubectl -o $@ chmod +x $@ $(KIND_DIR)/.kubectl-updated-$(K8S_VERSION): $(KUBECTL)-$(K8S_VERSION) diff --git a/libcalico-go/Makefile b/libcalico-go/Makefile index 92cd3ad5f6b..91749b4a446 100644 --- a/libcalico-go/Makefile +++ b/libcalico-go/Makefile @@ -6,6 +6,10 @@ LOCAL_CHECKS = goimports check-gen-files KIND_CONFIG = $(KIND_DIR)/kind-single.config +NETPOL_TAG = v0.1.5 +NETPOL_CRD_URL = https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/refs/tags/$(NETPOL_TAG)/config/crd/standard +NETPOL_ANP_CRD = policy.networking.k8s.io_adminnetworkpolicies.yaml + ############################################################################### # Download and include ../lib.Makefile # Additions to EXTRA_DOCKER_ARGS need to happen before the include since @@ -53,6 +57,8 @@ gen-crds: patch -s -p0 < ./config.patch # The first two lines are a newline and a yaml separator - remove them. $(DOCKER_GO_BUILD) sh -c 'find ./config/crd -name "*.yaml" | xargs sed -i -e 1,2d' + # Add K8S AdminNetworkPolicy CRD + curl $(NETPOL_CRD_URL)/$(NETPOL_ANP_CRD) -o ./config/crd/$(NETPOL_ANP_CRD) ./lib/upgrade/migrator/clients/v1/k8s/custom/zz_generated.deepcopy.go: $(UPGRADE_SRCS) $(DOCKER_GO_BUILD) sh -c 'deepcopy-gen \ @@ -90,7 +96,7 @@ gen-crds: # Static checks ############################################################################### # TODO: re-enable all linters -LINT_ARGS += --disable gosimple,unused,structcheck,errcheck,deadcode,varcheck,ineffassign,staticcheck,govet +LINT_ARGS += --disable gosimple,unused,errcheck,ineffassign,staticcheck .PHONY: check-gen-files check-gen-files: $(GENERATED_FILES) fix gen-crds diff --git a/libcalico-go/config/crd/crd.projectcalico.org_bgpfilters.yaml b/libcalico-go/config/crd/crd.projectcalico.org_bgpfilters.yaml index 49dc53f8e80..09db5e3eff7 100644 --- a/libcalico-go/config/crd/crd.projectcalico.org_bgpfilters.yaml +++ b/libcalico-go/config/crd/crd.projectcalico.org_bgpfilters.yaml @@ -49,6 +49,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -70,6 +83,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -91,6 +117,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -112,6 +151,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: diff --git a/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml b/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml index 8f83bd6b6d9..ecd3f24f546 100644 --- a/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml +++ b/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml @@ -264,6 +264,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -648,6 +659,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -686,10 +700,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, diff --git a/libcalico-go/config/crd/crd.projectcalico.org_globalnetworkpolicies.yaml b/libcalico-go/config/crd/crd.projectcalico.org_globalnetworkpolicies.yaml index bf4420ca1b8..039119087d7 100644 --- a/libcalico-go/config/crd/crd.projectcalico.org_globalnetworkpolicies.yaml +++ b/libcalico-go/config/crd/crd.projectcalico.org_globalnetworkpolicies.yaml @@ -794,10 +794,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -839,6 +839,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so diff --git a/libcalico-go/config/crd/crd.projectcalico.org_networkpolicies.yaml b/libcalico-go/config/crd/crd.projectcalico.org_networkpolicies.yaml index 6a927545207..b2a4c07797b 100644 --- a/libcalico-go/config/crd/crd.projectcalico.org_networkpolicies.yaml +++ b/libcalico-go/config/crd/crd.projectcalico.org_networkpolicies.yaml @@ -779,10 +779,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -820,6 +820,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so diff --git a/libcalico-go/config/crd/crd.projectcalico.org_tiers.yaml b/libcalico-go/config/crd/crd.projectcalico.org_tiers.yaml new file mode 100644 index 00000000000..78ad890a9e1 --- /dev/null +++ b/libcalico-go/config/crd/crd.projectcalico.org_tiers.yaml @@ -0,0 +1,62 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/libcalico-go/config/crd/policy.networking.k8s.io_adminnetworkpolicies.yaml b/libcalico-go/config/crd/policy.networking.k8s.io_adminnetworkpolicies.yaml new file mode 100644 index 00000000000..9494e478e5f --- /dev/null +++ b/libcalico-go/config/crd/policy.networking.k8s.io_adminnetworkpolicies.yaml @@ -0,0 +1,966 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/libcalico-go/lib/apis/crd.projectcalico.org/v1/tier_types.go b/libcalico-go/lib/apis/crd.projectcalico.org/v1/tier_types.go new file mode 100644 index 00000000000..464afadb39d --- /dev/null +++ b/libcalico-go/lib/apis/crd.projectcalico.org/v1/tier_types.go @@ -0,0 +1,32 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// +k8s:openapi-gen=true +// +kubebuilder:resource:scope=Cluster +type Tier struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec v3.TierSpec `json:"spec,omitempty"` +} diff --git a/libcalico-go/lib/apis/v1/openapi_generated.go b/libcalico-go/lib/apis/v1/openapi_generated.go index 652eb5863d5..4b0530f8aca 100644 --- a/libcalico-go/lib/apis/v1/openapi_generated.go +++ b/libcalico-go/lib/apis/v1/openapi_generated.go @@ -65,6 +65,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.ProfileMetadata": schema_libcalico_go_lib_apis_v1_ProfileMetadata(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.ProfileSpec": schema_libcalico_go_lib_apis_v1_ProfileSpec(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Rule": schema_libcalico_go_lib_apis_v1_Rule(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Tier": schema_libcalico_go_lib_apis_v1_Tier(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierList": schema_libcalico_go_lib_apis_v1_TierList(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierMetadata": schema_libcalico_go_lib_apis_v1_TierMetadata(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierSpec": schema_libcalico_go_lib_apis_v1_TierSpec(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.WorkloadEndpoint": schema_libcalico_go_lib_apis_v1_WorkloadEndpoint(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.WorkloadEndpointList": schema_libcalico_go_lib_apis_v1_WorkloadEndpointList(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.WorkloadEndpointMetadata": schema_libcalico_go_lib_apis_v1_WorkloadEndpointMetadata(ref), @@ -322,8 +326,7 @@ func schema_libcalico_go_lib_apis_v1_EndpointPort(ref common.ReferenceCallback) }, "protocol": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), }, }, "port": { @@ -389,8 +392,7 @@ func schema_libcalico_go_lib_apis_v1_EntityRule(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -436,8 +438,7 @@ func schema_libcalico_go_lib_apis_v1_EntityRule(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -889,8 +890,7 @@ func schema_libcalico_go_lib_apis_v1_IPPoolMetadata(ref common.ReferenceCallback }, "cidr": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), }, }, }, @@ -1212,7 +1212,7 @@ func schema_libcalico_go_lib_apis_v1_Policy(ref common.ReferenceCallback) common return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Policy contains information about a security Policy resource. This contains a set of security rules to apply. Security policies allow a selector-based security model which can override the security profiles directly referenced by an endpoint.\n\nEach policy must do one of the following:\n\n - Match the packet and apply an \"allow\" action; this immediately accepts the packet, skipping\n all further policies and profiles. This is not recommended in general, because it prevents\n further policy from being executed.\n - Match the packet and apply a \"deny\" action; this drops the packet immediately, skipping all\n further policy and profiles.\n - Fail to match the packet; in which case the packet proceeds to the next policy. If there\n are no more policies then the packet is dropped.\n\nCalico implements the security policy for each endpoint individually and only the policies that have matching selectors are implemented. This ensures that the number of rules that actually need to be inserted into the kernel is proportional to the number of local endpoints rather than the total amount of policy.", + Description: "Policy contains information about a tiered security Policy resource. This contains a set of security rules to apply. Security policies allow a selector-based security model which can override the security profiles directly referenced by an endpoint.\n\nEach policy must do one of the following:\n\n - Match the packet and apply a “next-tier” action; this skips the rest of the tier, deferring\n to the next tier (or the explicit profiles if this is the last tier.\n - Match the packet and apply an “allow” action; this immediately accepts the packet, skipping\n all further tiers and profiles. This is not recommended in general, because it prevents\n further policy from being executed.\n - Match the packet and apply a \"deny\" action; this drops the packet immediately, skipping all\n further tiers and profiles.\n - Fail to match the packet; in which case the packet proceeds to the next policy in the tier.\n If there are no more policies in the tier then the packet is dropped.\n\nNote:\n\n\tIf no policies in a tier match an endpoint then the packet skips the tier completely. The\n\t“default deny” behavior described above only applies if some of the policies in a tier match\n\tthe endpoint.\n\nCalico implements the security policy for each endpoint individually and only the policies that have matching selectors are implemented. This ensures that the number of rules that actually need to be inserted into the kernel is proportional to the number of local endpoints rather than the total amount of policy. If no policies in a tier match a given endpoint then that tier is skipped.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "TypeMetadata": { @@ -1303,6 +1303,13 @@ func schema_libcalico_go_lib_apis_v1_PolicyMetadata(ref common.ReferenceCallback Format: "", }, }, + "tier": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the tier that this policy belongs to. If this is omitted, the default tier (name is \"default\") is assumed. The specified tier must exist in order to create security policies within the tier, the \"default\" tier is created automatically if it does not exist, this means for deployments requiring only a single Tier, the tier name may be omitted on all policy management requests.", + Type: []string{"string"}, + Format: "", + }, + }, "annotations": { SchemaProps: spec.SchemaProps{ Description: "Arbitrary key-value information to be used by clients.", @@ -1337,7 +1344,7 @@ func schema_libcalico_go_lib_apis_v1_PolicySpec(ref common.ReferenceCallback) co Properties: map[string]spec.Schema{ "order": { SchemaProps: spec.SchemaProps{ - Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\".", + Description: "Order is an optional field that specifies the order in which the policy is applied within a given tier. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order and within the same Tier will be applied in alphanumerical order based on the Policy \"Name\".", Type: []string{"number"}, Format: "double", }, @@ -1662,6 +1669,129 @@ func schema_libcalico_go_lib_apis_v1_Rule(ref common.ReferenceCallback) common.O } } +func schema_libcalico_go_lib_apis_v1_Tier(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Tier contains the details of a security policy tier resource. A tier contains a set of policies that are applied to packets. Multiple tiers may be created and each tier is applied in the order specified in the tier specification.\n\nSee Policy for more information.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "TypeMetadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"), + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierMetadata"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierSpec"), + }, + }, + }, + Required: []string{"TypeMetadata"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierMetadata", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierSpec", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"}, + } +} + +func schema_libcalico_go_lib_apis_v1_TierList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "A TierList contains a list of tier resources. List types are returned from List() enumerations in the client interface.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "TypeMetadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"), + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ListMetadata"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Tier"), + }, + }, + }, + }, + }, + }, + Required: []string{"TypeMetadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Tier", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ListMetadata", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"}, + } +} + +func schema_libcalico_go_lib_apis_v1_TierMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TierMetadata contains the metadata for a security policy Tier.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ObjectMetadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ObjectMetadata"), + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"ObjectMetadata"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ObjectMetadata"}, + } +} + +func schema_libcalico_go_lib_apis_v1_TierSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TierSpec contains the specification for a security policy Tier.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "order": { + SchemaProps: spec.SchemaProps{ + Description: "Order is an optional field that specifies the order in which the tier is applied. Tiers with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the tier will be applied last. Tiers with identical order will be applied in alphanumerical order based on the Tier \"Name\".", + Type: []string{"number"}, + Format: "double", + }, + }, + }, + }, + }, + } +} + func schema_libcalico_go_lib_apis_v1_WorkloadEndpoint(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1823,8 +1953,7 @@ func schema_libcalico_go_lib_apis_v1_WorkloadEndpointSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), }, }, }, @@ -1905,8 +2034,7 @@ func schema_libcalico_go_lib_apis_v1_WorkloadEndpointSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), }, }, }, diff --git a/libcalico-go/lib/apis/v1/policy.go b/libcalico-go/lib/apis/v1/policy.go index 9d4e7e7a2e6..c8a4cd40bcd 100644 --- a/libcalico-go/lib/apis/v1/policy.go +++ b/libcalico-go/lib/apis/v1/policy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016,2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,24 +20,32 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" ) -// Policy contains information about a security Policy resource. This contains a set of +// Policy contains information about a tiered security Policy resource. This contains a set of // security rules to apply. Security policies allow a selector-based security model which can override // the security profiles directly referenced by an endpoint. // // Each policy must do one of the following: // -// - Match the packet and apply an "allow" action; this immediately accepts the packet, skipping -// all further policies and profiles. This is not recommended in general, because it prevents +// - Match the packet and apply a “next-tier” action; this skips the rest of the tier, deferring +// to the next tier (or the explicit profiles if this is the last tier. +// - Match the packet and apply an “allow” action; this immediately accepts the packet, skipping +// all further tiers and profiles. This is not recommended in general, because it prevents // further policy from being executed. // - Match the packet and apply a "deny" action; this drops the packet immediately, skipping all -// further policy and profiles. -// - Fail to match the packet; in which case the packet proceeds to the next policy. If there -// are no more policies then the packet is dropped. +// further tiers and profiles. +// - Fail to match the packet; in which case the packet proceeds to the next policy in the tier. +// If there are no more policies in the tier then the packet is dropped. +// +// Note: +// +// If no policies in a tier match an endpoint then the packet skips the tier completely. The +// “default deny” behavior described above only applies if some of the policies in a tier match +// the endpoint. // // Calico implements the security policy for each endpoint individually and only the policies that // have matching selectors are implemented. This ensures that the number of rules that actually need // to be inserted into the kernel is proportional to the number of local endpoints rather than the -// total amount of policy. +// total amount of policy. If no policies in a tier match a given endpoint then that tier is skipped. type Policy struct { unversioned.TypeMetadata Metadata PolicyMetadata `json:"metadata,omitempty"` @@ -61,17 +69,24 @@ type PolicyMetadata struct { // The name of the selector-based security policy. Name string `json:"name,omitempty" validate:"omitempty,namespacedName"` + // The name of the tier that this policy belongs to. If this is omitted, the default + // tier (name is "default") is assumed. The specified tier must exist in order to create + // security policies within the tier, the "default" tier is created automatically if it + // does not exist, this means for deployments requiring only a single Tier, the tier name + // may be omitted on all policy management requests. + Tier string `json:"tier,omitempty" validate:"omitempty,name"` + // Arbitrary key-value information to be used by clients. Annotations map[string]string `json:"annotations,omitempty" validate:"omitempty"` } // PolicySpec contains the specification for a selector-based security Policy resource. type PolicySpec struct { - // Order is an optional field that specifies the order in which the policy is applied. - // Policies with higher "order" are applied after those with lower + // Order is an optional field that specifies the order in which the policy is applied + // within a given tier. Policies with higher "order" are applied after those with lower // order. If the order is omitted, it may be considered to be "infinite" - i.e. the - // policy will be applied last. Policies with identical order will be applied in - // alphanumerical order based on the Policy "Name". + // policy will be applied last. Policies with identical order and within the same Tier + // will be applied in alphanumerical order based on the Policy "Name". Order *float64 `json:"order,omitempty"` // The ordered set of ingress rules. Each rule contains a set of packet match criteria and diff --git a/libcalico-go/lib/apis/v1/tier.go b/libcalico-go/lib/apis/v1/tier.go new file mode 100644 index 00000000000..e24411137e9 --- /dev/null +++ b/libcalico-go/lib/apis/v1/tier.go @@ -0,0 +1,88 @@ +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "fmt" + + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" +) + +// Tier contains the details of a security policy tier resource. A tier contains a set of +// policies that are applied to packets. Multiple tiers may be created and each tier is applied +// in the order specified in the tier specification. +// +// See Policy for more information. +type Tier struct { + unversioned.TypeMetadata + Metadata TierMetadata `json:"metadata,omitempty"` + Spec TierSpec `json:"spec,omitempty"` +} + +func (t Tier) GetResourceMetadata() unversioned.ResourceMetadata { + return t.Metadata +} + +// String() returns the human-readable string representation of a Tier instance +// which is defined by its Name. +func (t Tier) String() string { + return fmt.Sprintf("Tier(Name=%s)", t.Metadata.Name) +} + +// TierMetadata contains the metadata for a security policy Tier. +type TierMetadata struct { + unversioned.ObjectMetadata + Name string `json:"name,omitempty" validate:"omitempty,name"` +} + +// TierSpec contains the specification for a security policy Tier. +type TierSpec struct { + // Order is an optional field that specifies the order in which the tier is applied. + // Tiers with higher "order" are applied after those with lower order. If the order + // is omitted, it may be considered to be "infinite" - i.e. the tier will be applied + // last. Tiers with identical order will be applied in alphanumerical order based + // on the Tier "Name". + Order *float64 `json:"order,omitempty"` +} + +// NewTier creates a new (zeroed) Tier struct with the TypeMetadata initialised to the current +// version. +func NewTier() *Tier { + return &Tier{ + TypeMetadata: unversioned.TypeMetadata{ + Kind: "tier", + APIVersion: unversioned.VersionCurrent, + }, + } +} + +// A TierList contains a list of tier resources. List types are returned from List() +// enumerations in the client interface. +type TierList struct { + unversioned.TypeMetadata + Metadata unversioned.ListMetadata `json:"metadata,omitempty"` + Items []Tier `json:"items" validate:"dive"` +} + +// NewTier creates a new (zeroed) Tier struct with the TypeMetadata initialised to the current +// version. +func NewTierList() *TierList { + return &TierList{ + TypeMetadata: unversioned.TypeMetadata{ + Kind: "tierList", + APIVersion: unversioned.VersionCurrent, + }, + } +} diff --git a/libcalico-go/lib/apis/v3/openapi_generated.go b/libcalico-go/lib/apis/v3/openapi_generated.go index ca0557ed221..b4d15e457a9 100644 --- a/libcalico-go/lib/apis/v3/openapi_generated.go +++ b/libcalico-go/lib/apis/v3/openapi_generated.go @@ -65,6 +65,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.ProfileMetadata": schema_libcalico_go_lib_apis_v1_ProfileMetadata(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.ProfileSpec": schema_libcalico_go_lib_apis_v1_ProfileSpec(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Rule": schema_libcalico_go_lib_apis_v1_Rule(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Tier": schema_libcalico_go_lib_apis_v1_Tier(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierList": schema_libcalico_go_lib_apis_v1_TierList(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierMetadata": schema_libcalico_go_lib_apis_v1_TierMetadata(ref), + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierSpec": schema_libcalico_go_lib_apis_v1_TierSpec(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.WorkloadEndpoint": schema_libcalico_go_lib_apis_v1_WorkloadEndpoint(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.WorkloadEndpointList": schema_libcalico_go_lib_apis_v1_WorkloadEndpointList(ref), "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.WorkloadEndpointMetadata": schema_libcalico_go_lib_apis_v1_WorkloadEndpointMetadata(ref), @@ -348,8 +352,7 @@ func schema_libcalico_go_lib_apis_v1_EndpointPort(ref common.ReferenceCallback) }, "protocol": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), }, }, "port": { @@ -415,8 +418,7 @@ func schema_libcalico_go_lib_apis_v1_EntityRule(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -462,8 +464,7 @@ func schema_libcalico_go_lib_apis_v1_EntityRule(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Port"), }, }, }, @@ -915,8 +916,7 @@ func schema_libcalico_go_lib_apis_v1_IPPoolMetadata(ref common.ReferenceCallback }, "cidr": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), }, }, }, @@ -1238,7 +1238,7 @@ func schema_libcalico_go_lib_apis_v1_Policy(ref common.ReferenceCallback) common return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Policy contains information about a security Policy resource. This contains a set of security rules to apply. Security policies allow a selector-based security model which can override the security profiles directly referenced by an endpoint.\n\nEach policy must do one of the following:\n\n - Match the packet and apply an \"allow\" action; this immediately accepts the packet, skipping\n all further policies and profiles. This is not recommended in general, because it prevents\n further policy from being executed.\n - Match the packet and apply a \"deny\" action; this drops the packet immediately, skipping all\n further policy and profiles.\n - Fail to match the packet; in which case the packet proceeds to the next policy. If there\n are no more policies then the packet is dropped.\n\nCalico implements the security policy for each endpoint individually and only the policies that have matching selectors are implemented. This ensures that the number of rules that actually need to be inserted into the kernel is proportional to the number of local endpoints rather than the total amount of policy.", + Description: "Policy contains information about a tiered security Policy resource. This contains a set of security rules to apply. Security policies allow a selector-based security model which can override the security profiles directly referenced by an endpoint.\n\nEach policy must do one of the following:\n\n - Match the packet and apply a “next-tier” action; this skips the rest of the tier, deferring\n to the next tier (or the explicit profiles if this is the last tier.\n - Match the packet and apply an “allow” action; this immediately accepts the packet, skipping\n all further tiers and profiles. This is not recommended in general, because it prevents\n further policy from being executed.\n - Match the packet and apply a \"deny\" action; this drops the packet immediately, skipping all\n further tiers and profiles.\n - Fail to match the packet; in which case the packet proceeds to the next policy in the tier.\n If there are no more policies in the tier then the packet is dropped.\n\nNote:\n\n\tIf no policies in a tier match an endpoint then the packet skips the tier completely. The\n\t“default deny” behavior described above only applies if some of the policies in a tier match\n\tthe endpoint.\n\nCalico implements the security policy for each endpoint individually and only the policies that have matching selectors are implemented. This ensures that the number of rules that actually need to be inserted into the kernel is proportional to the number of local endpoints rather than the total amount of policy. If no policies in a tier match a given endpoint then that tier is skipped.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "TypeMetadata": { @@ -1329,6 +1329,13 @@ func schema_libcalico_go_lib_apis_v1_PolicyMetadata(ref common.ReferenceCallback Format: "", }, }, + "tier": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the tier that this policy belongs to. If this is omitted, the default tier (name is \"default\") is assumed. The specified tier must exist in order to create security policies within the tier, the \"default\" tier is created automatically if it does not exist, this means for deployments requiring only a single Tier, the tier name may be omitted on all policy management requests.", + Type: []string{"string"}, + Format: "", + }, + }, "annotations": { SchemaProps: spec.SchemaProps{ Description: "Arbitrary key-value information to be used by clients.", @@ -1363,7 +1370,7 @@ func schema_libcalico_go_lib_apis_v1_PolicySpec(ref common.ReferenceCallback) co Properties: map[string]spec.Schema{ "order": { SchemaProps: spec.SchemaProps{ - Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\".", + Description: "Order is an optional field that specifies the order in which the policy is applied within a given tier. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order and within the same Tier will be applied in alphanumerical order based on the Policy \"Name\".", Type: []string{"number"}, Format: "double", }, @@ -1688,6 +1695,129 @@ func schema_libcalico_go_lib_apis_v1_Rule(ref common.ReferenceCallback) common.O } } +func schema_libcalico_go_lib_apis_v1_Tier(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Tier contains the details of a security policy tier resource. A tier contains a set of policies that are applied to packets. Multiple tiers may be created and each tier is applied in the order specified in the tier specification.\n\nSee Policy for more information.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "TypeMetadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"), + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierMetadata"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierSpec"), + }, + }, + }, + Required: []string{"TypeMetadata"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierMetadata", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.TierSpec", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"}, + } +} + +func schema_libcalico_go_lib_apis_v1_TierList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "A TierList contains a list of tier resources. List types are returned from List() enumerations in the client interface.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "TypeMetadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"), + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ListMetadata"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Tier"), + }, + }, + }, + }, + }, + }, + Required: []string{"TypeMetadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1.Tier", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ListMetadata", "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.TypeMetadata"}, + } +} + +func schema_libcalico_go_lib_apis_v1_TierMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TierMetadata contains the metadata for a security policy Tier.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ObjectMetadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ObjectMetadata"), + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"ObjectMetadata"}, + }, + }, + Dependencies: []string{ + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned.ObjectMetadata"}, + } +} + +func schema_libcalico_go_lib_apis_v1_TierSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TierSpec contains the specification for a security policy Tier.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "order": { + SchemaProps: spec.SchemaProps{ + Description: "Order is an optional field that specifies the order in which the tier is applied. Tiers with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the tier will be applied last. Tiers with identical order will be applied in alphanumerical order based on the Tier \"Name\".", + Type: []string{"number"}, + Format: "double", + }, + }, + }, + }, + }, + } +} + func schema_libcalico_go_lib_apis_v1_WorkloadEndpoint(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1849,8 +1979,7 @@ func schema_libcalico_go_lib_apis_v1_WorkloadEndpointSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), }, }, }, @@ -1931,8 +2060,7 @@ func schema_libcalico_go_lib_apis_v1_WorkloadEndpointSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), + Ref: ref("github.com/projectcalico/calico/libcalico-go/lib/net.IPNet"), }, }, }, @@ -3076,8 +3204,7 @@ func schema_libcalico_go_lib_apis_v3_WorkloadEndpointPort(ref common.ReferenceCa }, "protocol": { SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), + Ref: ref("github.com/projectcalico/api/pkg/lib/numorstring.Protocol"), }, }, "port": { diff --git a/libcalico-go/lib/backend/api/api.go b/libcalico-go/lib/backend/api/api.go index 14bfd8e3fdc..94c79cefff4 100644 --- a/libcalico-go/lib/backend/api/api.go +++ b/libcalico-go/lib/backend/api/api.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -81,6 +81,8 @@ type Client interface { // revision is still current. // // Some keys are hierarchical, and Delete is a recursive operation. + // For example, deleting a Tier also deletes all the policies under + // that Tier. // // Any objects that were implicitly added by a Create operation should // also be removed when deleting the objects that implicitly created it. diff --git a/libcalico-go/lib/backend/k8s/conversion/adminnetworkpolicy_test.go b/libcalico-go/lib/backend/k8s/conversion/adminnetworkpolicy_test.go new file mode 100644 index 00000000000..f820b81516b --- /dev/null +++ b/libcalico-go/lib/backend/k8s/conversion/adminnetworkpolicy_test.go @@ -0,0 +1,1558 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package conversion + +import ( + "fmt" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/api/pkg/lib/numorstring" + kapiv1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + adminpolicy "sigs.k8s.io/network-policy-api/apis/v1alpha1" + + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" + cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" +) + +var _ = Describe("Test AdminNetworkPolicy conversion", func() { + // Use a single instance of the Converter for these tests. + c := NewConverter() + + convertToGNP := func( + anp *adminpolicy.AdminNetworkPolicy, + order float64, + expectedErr *cerrors.ErrorAdminPolicyConversion, + ) *apiv3.GlobalNetworkPolicy { + // Parse the policy. + pol, err := c.K8sAdminNetworkPolicyToCalico(anp) + + if expectedErr == nil { + Expect(err).To(BeNil()) + } else { + Expect(err).To(Equal(*expectedErr)) + } + + // Assert key fields are correct. + policyName := fmt.Sprintf("%v%v", names.K8sAdminNetworkPolicyNamePrefix, anp.Name) + Expect(pol.Key.(model.ResourceKey).Name).To(Equal(policyName)) + + gnp, ok := pol.Value.(*apiv3.GlobalNetworkPolicy) + Expect(ok).To(BeTrue()) + + // Make sure the type information is correct. + Expect(gnp.Kind).To(Equal(apiv3.KindGlobalNetworkPolicy)) + Expect(gnp.APIVersion).To(Equal(apiv3.GroupVersionCurrent)) + + // Assert value fields are correct. + Expect(*gnp.Spec.Order).To(Equal(order)) + Expect(gnp.Spec.Tier).To(Equal(names.AdminNetworkPolicyTierName)) + + return gnp + } + + It("should parse a basic k8s AdminNetworkPolicy to a GlobalNetworkPolicy", func() { + ports := []adminpolicy.AdminNetworkPolicyPort{{ + PortNumber: &adminpolicy.Port{ + Port: 80, + }, + }} + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 100, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "The first ingress rule", + Action: "Allow", + Ports: &ports, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + "k2": "v2", + }, + }, + }, + }, + }, + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(100.0), nil) + + // Check the selector is correct, and that the matches are sorted. + Expect(gnp.Spec.NamespaceSelector).To(Equal("label == 'value' && label2 == 'value2'")) + protoTCP := numorstring.ProtocolFromString("TCP") + Expect(gnp.Spec.Ingress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("The first ingress rule"), + Action: "Allow", + Protocol: &protoTCP, // Defaulted to TCP. + Source: apiv3.EntityRule{ + NamespaceSelector: "k == 'v' && k2 == 'v2'", + }, + Destination: apiv3.EntityRule{ + Ports: []numorstring.Port{numorstring.SinglePort(80)}, + }, + }, + )) + + // There should be no Egress rules + Expect(gnp.Spec.Egress).To(HaveLen(0)) + }) + + It("should drop rules with invalid action in a k8s AdminNetworkPolicy", func() { + ports := []adminpolicy.AdminNetworkPolicyPort{ + { + PortNumber: &adminpolicy.Port{Port: 80}, + }, + { + PortRange: &adminpolicy.PortRange{Start: 2000, End: 3000}, + }, + } + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 300, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Log", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + "k2": "v2", + }, + }, + }, + }, + }, + { + Name: "A random ingress rule 2", + Action: "Allow", + Ports: &ports, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k10": "v10", + "k20": "v20", + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + Ports: &ports, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + "k4": "v4", + }, + }, + }, + }, + }, + { + Name: "A random egress rule 2", + Action: "Drop", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k30": "v30", + "k40": "v40", + }, + }, + }, + }, + }, + }, + }, + } + + expectedErr := cerrors.ErrorAdminPolicyConversion{ + PolicyName: "test.policy", + Rules: []cerrors.ErrorAdminPolicyConversionRule{ + { + EgressRule: nil, + IngressRule: &adminpolicy.AdminNetworkPolicyIngressRule{ + Name: "A random ingress rule", + Action: "Log", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{"k2": "v2", "k": "v"}, + MatchExpressions: nil, + }, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: unsupported admin network policy action Log", + }, + { + IngressRule: nil, + EgressRule: &adminpolicy.AdminNetworkPolicyEgressRule{ + Name: "A random egress rule 2", + Action: "Drop", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{"k30": "v30", "k40": "v40"}, + MatchExpressions: nil, + }, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: unsupported admin network policy action Drop", + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(300.0), &expectedErr) + + protoTCP := numorstring.ProtocolFromString("TCP") + + Expect(len(gnp.Spec.Ingress)).To(Equal(1)) + Expect(gnp.Spec.Ingress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random ingress rule 2"), + Action: "Allow", + Protocol: &protoTCP, // Defaulted to TCP. + Source: apiv3.EntityRule{ + NamespaceSelector: "k10 == 'v10' && k20 == 'v20'", + }, + Destination: apiv3.EntityRule{ + Ports: []numorstring.Port{numorstring.SinglePort(80), {MinPort: 2000, MaxPort: 3000}}, + }, + }, + )) + + Expect(len(gnp.Spec.Egress)).To(Equal(1)) + Expect(gnp.Spec.Egress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random egress rule"), + Action: "Deny", + Protocol: &protoTCP, // Defaulted to TCP. + Source: apiv3.EntityRule{}, + Destination: apiv3.EntityRule{ + NamespaceSelector: "k3 == 'v3' && k4 == 'v4'", + Ports: []numorstring.Port{numorstring.SinglePort(80), {MinPort: 2000, MaxPort: 3000}}, + }, + }, + )) + }) + + It("should parse a k8s AdminNetworkPolicy with no ports", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 200, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Pass", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + "k2": "v2", + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + "k4": "v4", + }, + }, + }, + }, + }, + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(200.0), nil) + + Expect(gnp.Spec.Ingress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random ingress rule"), + Action: "Pass", + Protocol: nil, // We only default to TCP when ports exist + Source: apiv3.EntityRule{NamespaceSelector: "k == 'v' && k2 == 'v2'"}, + Destination: apiv3.EntityRule{}, + }, + )) + Expect(gnp.Spec.Egress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random egress rule"), + Action: "Deny", + Protocol: nil, // We only default to TCP when ports exist + Source: apiv3.EntityRule{}, + Destination: apiv3.EntityRule{NamespaceSelector: "k3 == 'v3' && k4 == 'v4'"}, + }, + )) + }) + + It("should drop rules with invalid ports in a k8s AdminNetworkPolicy", func() { + goodPorts := []adminpolicy.AdminNetworkPolicyPort{ + { + PortNumber: &adminpolicy.Port{Port: 80}, + }, + { + PortRange: &adminpolicy.PortRange{Start: 2000, End: 3000}, + }, + } + badPorts := []adminpolicy.AdminNetworkPolicyPort{ + { + PortNumber: &adminpolicy.Port{Port: 80}, + }, + { + PortRange: &adminpolicy.PortRange{Start: 1000, End: 10}, + }, + } + + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 300, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Pass", + Ports: &badPorts, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + "k2": "v2", + }, + }, + }, + }, + }, + { + Name: "A random ingress rule 2", + Action: "Allow", + Ports: &goodPorts, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k10": "v10", + "k20": "v20", + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + Ports: &goodPorts, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + "k4": "v4", + }, + }, + }, + }, + }, + { + Name: "A random egress rule 2", + Action: "Pass", + Ports: &badPorts, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k30": "v30", + "k40": "v40", + }, + }, + }, + }, + }, + }, + }, + } + + expectedErr := cerrors.ErrorAdminPolicyConversion{ + PolicyName: "test.policy", + Rules: []cerrors.ErrorAdminPolicyConversionRule{ + { + EgressRule: nil, + IngressRule: &adminpolicy.AdminNetworkPolicyIngressRule{ + Name: "A random ingress rule", + Action: "Pass", + Ports: &badPorts, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{"k2": "v2", "k": "v"}, + MatchExpressions: nil, + }, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: failed to parse k8s port: minimum port number (1000) is greater than maximum port number (10) in port range", + }, + { + IngressRule: nil, + EgressRule: &adminpolicy.AdminNetworkPolicyEgressRule{ + Name: "A random egress rule 2", + Action: "Pass", + Ports: &badPorts, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{"k30": "v30", "k40": "v40"}, + MatchExpressions: nil, + }, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: failed to parse k8s port: minimum port number (1000) is greater than maximum port number (10) in port range", + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(300.0), &expectedErr) + + protoTCP := numorstring.ProtocolFromString("TCP") + + Expect(len(gnp.Spec.Ingress)).To(Equal(1)) + Expect(gnp.Spec.Ingress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random ingress rule 2"), + Action: "Allow", + Protocol: &protoTCP, // Defaulted to TCP. + Source: apiv3.EntityRule{ + NamespaceSelector: "k10 == 'v10' && k20 == 'v20'", + }, + Destination: apiv3.EntityRule{ + Ports: []numorstring.Port{numorstring.SinglePort(80), {MinPort: 2000, MaxPort: 3000}}, + }, + }, + )) + + Expect(len(gnp.Spec.Egress)).To(Equal(1)) + Expect(gnp.Spec.Egress).To(ConsistOf( + apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random egress rule"), + Action: "Deny", + Protocol: &protoTCP, // Defaulted to TCP. + Source: apiv3.EntityRule{}, + Destination: apiv3.EntityRule{ + NamespaceSelector: "k3 == 'v3' && k4 == 'v4'", + Ports: []numorstring.Port{numorstring.SinglePort(80), {MinPort: 2000, MaxPort: 3000}}, + }, + }, + )) + }) + + It("should parse an AdminNetworkPolicy with no rules", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 500, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(500.0), nil) + + // Assert value fields are correct. + Expect(gnp.Spec.NamespaceSelector).To(Equal("label == 'value' && label2 == 'value2'")) + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + + // There should be no Egress rules + Expect(gnp.Spec.Egress).To(HaveLen(0)) + }) + + It("should parse an AdminNetworkPolicy with Namespaces subject and multiple peers", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Pass", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + }, + }, + }, + { + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k2": "v2", + }, + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + }, + }, + }, + { + Pods: &adminpolicy.NamespacedPod{ + NamespaceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k4": "v4", + }, + }, + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k5": "v5", + }, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.NamespaceSelector).To(Equal("label == 'value' && label2 == 'value2'")) + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s'")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(2)) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("k == 'v'")) + Expect(gnp.Spec.Ingress[1].Source.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Ingress[1].Source.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k2 == 'v2'")) + + Expect(gnp.Spec.Egress).To(HaveLen(2)) + Expect(gnp.Spec.Egress[0].Destination.NamespaceSelector).To(Equal("k3 == 'v3'")) + Expect(gnp.Spec.Egress[1].Destination.NamespaceSelector).To(Equal("k4 == 'v4'")) + Expect(gnp.Spec.Egress[1].Destination.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k5 == 'v5'")) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(2)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + Expect(gnp.Spec.Types[1]).To(Equal(apiv3.PolicyTypeEgress)) + }) + + It("should parse an AdminNetworkPolicy with Pods subject and multiple peers", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label2": "value2", + }, + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Pass", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + }, + }, + }, + { + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k2": "v2", + }, + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + }, + }, + }, + { + Pods: &adminpolicy.NamespacedPod{ + NamespaceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k4": "v4", + }, + }, + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k5": "v5", + }, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label2 == 'value2'")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(2)) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("k == 'v'")) + Expect(gnp.Spec.Ingress[1].Source.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Ingress[1].Source.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k2 == 'v2'")) + + Expect(gnp.Spec.Egress).To(HaveLen(2)) + Expect(gnp.Spec.Egress[0].Destination.NamespaceSelector).To(Equal("k3 == 'v3'")) + Expect(gnp.Spec.Egress[1].Destination.NamespaceSelector).To(Equal("k4 == 'v4'")) + Expect(gnp.Spec.Egress[1].Destination.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k5 == 'v5'")) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(2)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + Expect(gnp.Spec.Types[1]).To(Equal(apiv3.PolicyTypeEgress)) + }) + + It("should parse a k8s AdminNetworkPolicy with a DoesNotExist expression ", func() { + ports := []adminpolicy.AdminNetworkPolicyPort{ + { + PortNumber: &adminpolicy.Port{Port: 80}, + }, + } + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Allow", + Ports: &ports, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + {Key: "toast", Operator: metav1.LabelSelectorOpDoesNotExist}, + }, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + // Check the selector is correct, and that the matches are sorted. + Expect(gnp.Spec.Selector).To(Equal( + "projectcalico.org/orchestrator == 'k8s' && label == 'value' && label2 == 'value2'")) + protoTCP := numorstring.ProtocolFromString("TCP") + Expect(gnp.Spec.Ingress).To(ConsistOf( + apiv3.Rule{ + Action: "Allow", + Metadata: k8sAdminNetworkPolicyToCalicoMetadata("A random ingress rule"), + Protocol: &protoTCP, // Defaulted to TCP. + Source: apiv3.EntityRule{ + NamespaceSelector: "all()", + Selector: "projectcalico.org/orchestrator == 'k8s' && ! has(toast)", + }, + Destination: apiv3.EntityRule{ + Ports: []numorstring.Port{numorstring.SinglePort(80)}, + }, + }, + )) + + // There should be no Egress rules + Expect(gnp.Spec.Egress).To(HaveLen(0)) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(1)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + }) + + It("should parse an AdminNetworkPolicy with multiple peers and ports", func() { + ports := []adminpolicy.AdminNetworkPolicyPort{ + { + PortNumber: &adminpolicy.Port{Port: 80}, + }, + { + PortRange: &adminpolicy.PortRange{Start: 20, End: 30, Protocol: kapiv1.ProtocolUDP}, + }, + } + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Pass", + Ports: &ports, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + }, + }, + }, + { + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k2": "v2", + }, + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + Ports: &ports, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + }, + }, + }, + { + Pods: &adminpolicy.NamespacedPod{ + NamespaceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k4": "v4", + }, + }, + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k5": "v5", + }, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.NamespaceSelector).To(Equal("label == 'value' && label2 == 'value2'")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(4)) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("k == 'v'")) + Expect(gnp.Spec.Ingress[0].Destination.Ports).To(Equal([]numorstring.Port{numorstring.SinglePort(80)})) + + Expect(gnp.Spec.Ingress[1].Source.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Ingress[1].Source.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k2 == 'v2'")) + Expect(gnp.Spec.Ingress[1].Destination.Ports).To(Equal([]numorstring.Port{numorstring.SinglePort(80)})) + + Expect(gnp.Spec.Ingress[2].Source.NamespaceSelector).To(Equal("k == 'v'")) + Expect(gnp.Spec.Ingress[2].Destination.Ports).To(Equal([]numorstring.Port{{MinPort: 20, MaxPort: 30}})) + + Expect(gnp.Spec.Ingress[3].Source.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Ingress[3].Source.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k2 == 'v2'")) + Expect(gnp.Spec.Ingress[3].Destination.Ports).To(Equal([]numorstring.Port{{MinPort: 20, MaxPort: 30}})) + + Expect(gnp.Spec.Egress).To(HaveLen(4)) + Expect(gnp.Spec.Egress[0].Destination.NamespaceSelector).To(Equal("k3 == 'v3'")) + Expect(gnp.Spec.Egress[0].Destination.Ports).To(Equal([]numorstring.Port{numorstring.SinglePort(80)})) + + Expect(gnp.Spec.Egress[1].Destination.NamespaceSelector).To(Equal("k4 == 'v4'")) + Expect(gnp.Spec.Egress[1].Destination.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k5 == 'v5'")) + Expect(gnp.Spec.Egress[1].Destination.Ports).To(Equal([]numorstring.Port{numorstring.SinglePort(80)})) + + Expect(gnp.Spec.Egress[2].Destination.NamespaceSelector).To(Equal("k3 == 'v3'")) + Expect(gnp.Spec.Egress[2].Destination.Ports).To(Equal([]numorstring.Port{{MinPort: 20, MaxPort: 30}})) + + Expect(gnp.Spec.Egress[3].Destination.NamespaceSelector).To(Equal("k4 == 'v4'")) + Expect(gnp.Spec.Egress[3].Destination.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && k5 == 'v5'")) + Expect(gnp.Spec.Egress[3].Destination.Ports).To(Equal([]numorstring.Port{{MinPort: 20, MaxPort: 30}})) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(2)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + Expect(gnp.Spec.Types[1]).To(Equal(apiv3.PolicyTypeEgress)) + }) + + It("should parse an AdminNetworkPolicy with empty namespaces in Subject", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 500, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{}, + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(500.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + Expect(gnp.Spec.Egress).To(HaveLen(0)) + }) + + It("should parse an AdminNetworkPolicy with empty podSelector in Subject", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{}, + }, + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + Expect(gnp.Spec.Egress).To(HaveLen(0)) + }) + + It("should parse an AdminNetworkPolicy with a rule with namespaceSelector", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Allow", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "namespaceRole": "dev", + "namespaceFoo": "bar", + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label == 'value'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(1)) + Expect(gnp.Spec.Ingress[0].Source.Selector).To(BeZero()) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("namespaceFoo == 'bar' && namespaceRole == 'dev'")) + + // There should be no Egress rules. + Expect(gnp.Spec.Egress).To(HaveLen(0)) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(1)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + }) + + It("should parse an AdminNetworkPolicy with a rule with podSelector", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Allow", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "namespaceRole": "dev", + "namespaceFoo": "bar", + }, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label == 'value'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + + Expect(len(gnp.Spec.Egress)).To(Equal(1)) + Expect(gnp.Spec.Egress[0].Destination.NamespaceSelector).To(Equal("all()")) + Expect(gnp.Spec.Egress[0].Destination.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && namespaceFoo == 'bar' && namespaceRole == 'dev'")) + + // There should be no Ingress rules. + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(1)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeEgress)) + }) + + It("should faild parsing an AdminNetworkPolicy with a rule with neither namespaces or pods set", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Allow", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: nil, + Pods: nil, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Pass", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: nil, + Pods: nil, + }, + }, + }, + }, + }, + } + + expectedErr := cerrors.ErrorAdminPolicyConversion{ + PolicyName: "test.policy", + Rules: []cerrors.ErrorAdminPolicyConversionRule{ + { + EgressRule: nil, + IngressRule: &adminpolicy.AdminNetworkPolicyIngressRule{ + Name: "A random ingress rule", + Action: "Allow", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: nil, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: none of supported fields in 'From' is set.", + }, + { + IngressRule: nil, + EgressRule: &adminpolicy.AdminNetworkPolicyEgressRule{ + Name: "A random egress rule", + Action: "Pass", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: nil, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: none of supported fields in 'To' is set.", + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), &expectedErr) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label == 'value'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + + // There should be no rules. + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + Expect(gnp.Spec.Egress).To(HaveLen(0)) + }) + + It("should parse an AdminNetworkPolicy with a rule with empty namespaceSelector", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Allow", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label == 'value'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(1)) + Expect(gnp.Spec.Ingress[0].Source.Selector).To(BeZero()) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("all()")) + + // There should be no Egress rules. + Expect(gnp.Spec.Egress).To(HaveLen(0)) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(1)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + }) + + It("should parse an AdminNetworkPolicy with a rule with empty podSelector", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Pass", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Pods: &adminpolicy.NamespacedPod{ + NamespaceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }, + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label == 'value'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + + Expect(len(gnp.Spec.Egress)).To(Equal(1)) + Expect(gnp.Spec.Egress[0].Destination.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s'")) + Expect(gnp.Spec.Egress[0].Destination.NamespaceSelector).To(Equal("all()")) + + // There should be no Ingress rules. + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(1)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeEgress)) + }) + + It("should parse an AdminNetworkPolicy with a rule with a rule with both Namespaces and Pods", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 1000, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Deny", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Pods: &adminpolicy.NamespacedPod{ + NamespaceSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "namespaceRole": "dev", + "namespaceFoo": "bar", + }, + }, + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "podA": "B", + "podC": "D", + }, + }, + }, + }, + }, + }, + }, + }, + } + + gnp := convertToGNP(&anp, float64(1000.0), nil) + + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && label == 'value'")) + Expect(gnp.Spec.NamespaceSelector).To(Equal("all()")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(1)) + Expect(gnp.Spec.Ingress[0].Source.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s' && podA == 'B' && podC == 'D'")) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("namespaceFoo == 'bar' && namespaceRole == 'dev'")) + + // There should be no Egress rules. + Expect(gnp.Spec.Egress).To(HaveLen(0)) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(1)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + }) + + It("should parse an AdminNetworkPolicy with a Subject with MatchExpressions", func() { + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 500, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "k", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"v1", "v2"}, + }, + }, + }, + }, + }, + } + + // Convert the policy + gnp := convertToGNP(&anp, float64(500.0), nil) + + // Assert value fields are correct. + Expect(gnp.Spec.NamespaceSelector).To(Equal("k in { 'v1', 'v2' }")) + Expect(gnp.Spec.Selector).To(Equal("projectcalico.org/orchestrator == 'k8s'")) + Expect(gnp.Spec.Ingress).To(HaveLen(0)) + + // There should be no Egress rules + Expect(gnp.Spec.Egress).To(HaveLen(0)) + }) + + It("should replace an unsupported AdminNeworkPolicy rule with Deny action with a deny-all one", func() { + ports := []adminpolicy.AdminNetworkPolicyPort{{ + PortNumber: &adminpolicy.Port{Port: 80}, + }} + + badPorts := []adminpolicy.AdminNetworkPolicyPort{{ + PortRange: &adminpolicy.PortRange{Start: 40, End: 20, Protocol: kapiv1.ProtocolUDP}, + }} + anp := adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 600, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + "label2": "value2", + }, + }, + }, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Name: "A random ingress rule", + Action: "Pass", + Ports: &ports, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + }, + }, + }, + }, + }, + { + Name: "A random ingress rule 2", + Action: "Pass", + Ports: &badPorts, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k": "v", + }, + }, + }, + }, + }, + }, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Name: "A random egress rule", + Action: "Deny", + Ports: &badPorts, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k3": "v3", + }, + }, + }, + }, + }, + { + Name: "A random egress rule 2", + Action: "Deny", + Ports: &ports, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k4": "v4", + }, + }, + }, + }, + }, + }, + }, + } + + expectedErr := cerrors.ErrorAdminPolicyConversion{ + PolicyName: "test.policy", + Rules: []cerrors.ErrorAdminPolicyConversionRule{ + { + EgressRule: nil, + IngressRule: &adminpolicy.AdminNetworkPolicyIngressRule{ + Name: "A random ingress rule 2", + Action: "Pass", + Ports: &badPorts, + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{"k": "v"}, + MatchExpressions: nil, + }, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: failed to parse k8s port: minimum port number (40) is greater than maximum port number (20) in port range", + }, + { + IngressRule: nil, + EgressRule: &adminpolicy.AdminNetworkPolicyEgressRule{ + Name: "A random egress rule", + Action: "Deny", + Ports: &badPorts, + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{"k3": "v3"}, + MatchExpressions: nil, + }, + Pods: nil, + }, + }, + }, + Reason: "k8s rule couldn't be converted: failed to parse k8s port: minimum port number (40) is greater than maximum port number (20) in port range", + }, + }, + } + + gnp := convertToGNP(&anp, float64(600.0), &expectedErr) + + Expect(gnp.Spec.NamespaceSelector).To(Equal("label == 'value' && label2 == 'value2'")) + + Expect(len(gnp.Spec.Ingress)).To(Equal(1)) + Expect(gnp.Spec.Ingress[0].Source.NamespaceSelector).To(Equal("k == 'v'")) + Expect(gnp.Spec.Ingress[0].Destination.Ports).To(Equal([]numorstring.Port{numorstring.SinglePort(80)})) + + Expect(gnp.Spec.Egress).To(HaveLen(2)) + Expect(gnp.Spec.Egress[0].Destination.NamespaceSelector).To(BeZero()) + Expect(gnp.Spec.Egress[0]).To(Equal(apiv3.Rule{ + Action: apiv3.Deny, + })) + + Expect(gnp.Spec.Egress[1].Destination.NamespaceSelector).To(Equal("k4 == 'v4'")) + Expect(gnp.Spec.Egress[1].Destination.Selector).To(BeZero()) + Expect(gnp.Spec.Egress[1].Destination.Ports).To(Equal([]numorstring.Port{numorstring.SinglePort(80)})) + + // Check that Types field exists and has only 'ingress' + Expect(len(gnp.Spec.Types)).To(Equal(2)) + Expect(gnp.Spec.Types[0]).To(Equal(apiv3.PolicyTypeIngress)) + Expect(gnp.Spec.Types[1]).To(Equal(apiv3.PolicyTypeEgress)) + }) +}) diff --git a/libcalico-go/lib/backend/k8s/conversion/constants.go b/libcalico-go/lib/backend/k8s/conversion/constants.go index 504f4d4fefa..c7fa01ad0a1 100644 --- a/libcalico-go/lib/backend/k8s/conversion/constants.go +++ b/libcalico-go/lib/backend/k8s/conversion/constants.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package conversion const ( NamespaceLabelPrefix = "pcns." NamespaceProfileNamePrefix = "kns." - K8sNetworkPolicyNamePrefix = "knp.default." ServiceAccountLabelPrefix = "pcsa." ServiceAccountProfileNamePrefix = "ksa." @@ -44,4 +43,8 @@ const ( // NameLabel is a label that can be used to match a serviceaccount or namespace // name exactly. NameLabel = "projectcalico.org/name" + + // AdminPolicyRuleNameLabel is a label that show a rule's name before conversion to Calico data model. + // As an example, it holds an admin network policy rule name before conversion to GNPs. + AdminPolicyRuleNameLabel = "name" ) diff --git a/libcalico-go/lib/backend/k8s/conversion/conversion.go b/libcalico-go/lib/backend/k8s/conversion/conversion.go index d8eea0e24f5..bca4bf6aa9c 100644 --- a/libcalico-go/lib/backend/k8s/conversion/conversion.go +++ b/libcalico-go/lib/backend/k8s/conversion/conversion.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,10 +21,12 @@ import ( "strings" "github.com/google/uuid" + "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus" kapiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + adminpolicy "sigs.k8s.io/network-policy-api/apis/v1alpha1" discovery "k8s.io/api/discovery/v1" networkingv1 "k8s.io/api/networking/v1" @@ -59,6 +61,7 @@ type Converter interface { HasIPAddress(pod *kapiv1.Pod) bool StagedKubernetesNetworkPolicyToStagedName(stagedK8sName string) string K8sNetworkPolicyToCalico(np *networkingv1.NetworkPolicy) (*model.KVPair, error) + K8sAdminNetworkPolicyToCalico(anp *adminpolicy.AdminNetworkPolicy) (*model.KVPair, error) EndpointSliceToKVP(svc *discovery.EndpointSlice) (*model.KVPair, error) ServiceToKVP(service *kapiv1.Service) (*model.KVPair, error) ProfileNameToNamespace(profileName string) (string, error) @@ -245,7 +248,7 @@ func getPodIPs(pod *kapiv1.Pod) ([]*cnet.IPNet, error) { // StagedKubernetesNetworkPolicyToStagedName converts a StagedKubernetesNetworkPolicy name into a StagedNetworkPolicy name func (c converter) StagedKubernetesNetworkPolicyToStagedName(stagedK8sName string) string { - return fmt.Sprintf(K8sNetworkPolicyNamePrefix + stagedK8sName) + return names.K8sNetworkPolicyNamePrefix + stagedK8sName } // EndpointSliceToKVP converts a k8s EndpointSlice to a model.KVPair. @@ -273,10 +276,390 @@ func (c converter) ServiceToKVP(service *kapiv1.Service) (*model.KVPair, error) }, nil } +// K8sAdminNetworkPolicyToCalico converts a k8s AdminNetworkPolicy to a model.KVPair. +func (c converter) K8sAdminNetworkPolicyToCalico(anp *adminpolicy.AdminNetworkPolicy) (*model.KVPair, error) { + // Pull out important fields. + policyName := names.K8sAdminNetworkPolicyNamePrefix + anp.Name + order := float64(anp.Spec.Priority) + errorTracker := cerrors.ErrorAdminPolicyConversion{PolicyName: anp.Name} + + // Generate the ingress rules list. + var ingressRules []apiv3.Rule + for _, r := range anp.Spec.Ingress { + rules, err := k8sANPIngressRuleToCalico(r) + if err != nil { + log.WithError(err).Warn("dropping k8s rule that couldn't be converted.") + // Add rule to conversion error slice + errorTracker.BadIngressRule(&r, fmt.Sprintf("k8s rule couldn't be converted: %s", err)) + failClosedRule := k8sANPHandleFailedRules(r.Action) + if failClosedRule != nil { + ingressRules = append(ingressRules, *failClosedRule) + } + } else { + ingressRules = append(ingressRules, rules...) + } + } + + // Generate the egress rules list. + var egressRules []apiv3.Rule + for _, r := range anp.Spec.Egress { + rules, err := k8sANPEgressRuleToCalico(r) + if err != nil { + log.WithError(err).Warn("dropping k8s rule that couldn't be converted.") + // Add rule to conversion error slice + errorTracker.BadEgressRule(&r, fmt.Sprintf("k8s rule couldn't be converted: %s", err)) + failClosedRule := k8sANPHandleFailedRules(r.Action) + if failClosedRule != nil { + egressRules = append(egressRules, *failClosedRule) + } + } else { + egressRules = append(egressRules, rules...) + } + } + + // Calculate Types setting. + policyTypes := []apiv3.PolicyType{} + if len(anp.Spec.Ingress) != 0 { + policyTypes = append(policyTypes, apiv3.PolicyTypeIngress) + } + if len(anp.Spec.Egress) != 0 { + policyTypes = append(policyTypes, apiv3.PolicyTypeEgress) + } + + // Either Namespaces or Pods is set. Use one of them to populate the selectors. + var nsSelector, podSelector string + if anp.Spec.Subject.Namespaces != nil { + nsSelector = k8sSelectorToCalico(anp.Spec.Subject.Namespaces, SelectorNamespace) + // Make sure projectcalico.org/orchestrator == 'k8s' label is added to exclude heps. + podSelector = k8sSelectorToCalico(nil, SelectorPod) + } else { + nsSelector = k8sSelectorToCalico(&anp.Spec.Subject.Pods.NamespaceSelector, SelectorNamespace) + podSelector = k8sSelectorToCalico(&anp.Spec.Subject.Pods.PodSelector, SelectorPod) + } + + var uid types.UID + var err error + if anp.UID != "" { + uid, err = ConvertUID(anp.UID) + if err != nil { + return nil, err + } + } + + gnp := apiv3.NewGlobalNetworkPolicy() + gnp.ObjectMeta = metav1.ObjectMeta{ + Name: policyName, + CreationTimestamp: anp.CreationTimestamp, + UID: uid, + ResourceVersion: anp.ResourceVersion, + } + gnp.Spec = apiv3.GlobalNetworkPolicySpec{ + Tier: names.AdminNetworkPolicyTierName, + Order: &order, + NamespaceSelector: nsSelector, + Selector: podSelector, + Ingress: ingressRules, + Egress: egressRules, + Types: policyTypes, + } + + // Build the KVPair. + kvp := &model.KVPair{ + Key: model.ResourceKey{ + Name: policyName, + Kind: apiv3.KindGlobalNetworkPolicy, + }, + Value: gnp, + Revision: anp.ResourceVersion, + } + + // Return the KVPair with conversion errors if applicable + return kvp, errorTracker.GetError() +} + +func k8sANPHandleFailedRules(action adminpolicy.AdminNetworkPolicyRuleAction) *apiv3.Rule { + if action == adminpolicy.AdminNetworkPolicyRuleActionDeny { + logrus.Warn("replacing failed rule with a deny-all one.") + return &apiv3.Rule{ + Action: apiv3.Deny, + } + } + return nil +} + +func k8sANPIngressRuleToCalico(rule adminpolicy.AdminNetworkPolicyIngressRule) ([]apiv3.Rule, error) { + rules := []apiv3.Rule{} + + action, err := K8sAdminNetworkPolicyActionToCalico(rule.Action) + if err != nil { + return nil, err + } + + // If there no ports, represent that as zero struct. + ports := []adminpolicy.AdminNetworkPolicyPort{{}} + if rule.Ports != nil && len(*rule.Ports) != 0 { + ports = *rule.Ports + } + + protocolPorts := map[string][]numorstring.Port{} + + for _, port := range ports { + protocol, calicoPort, err := k8sAdminPolicyPortToCalicoFields(&port) + if err != nil { + return nil, fmt.Errorf("failed to parse k8s port: %s", err) + } + + if protocol == nil && calicoPort == nil { + // If nil, no ports were specified, or an empty port struct was provided, which we translate to allowing all. + // We want to use a nil protocol and a nil list of ports, which will allow any destination (for ingress). + // Given we're gonna allow all, we may as well break here and keep only this rule + protocolPorts = map[string][]numorstring.Port{"": nil} + break + } + + pStr := protocol.String() + // treat nil as 'all ports' + if calicoPort == nil { + protocolPorts[pStr] = nil + } else if _, ok := protocolPorts[pStr]; !ok || len(protocolPorts[pStr]) > 0 { + // don't overwrite a nil (allow all ports) if present; if no ports yet for this protocol + // or 1+ ports which aren't 'all ports', then add the present ports + protocolPorts[pStr] = append(protocolPorts[pStr], *calicoPort) + } + } + + protocols := make([]string, 0, len(protocolPorts)) + for k := range protocolPorts { + protocols = append(protocols, k) + } + // Ensure deterministic output + sort.Strings(protocols) + + // Combine destinations with sources to generate rules. We generate one rule per protocol, + // with each rule containing all the allowed ports. + for _, protocolStr := range protocols { + calicoPorts := protocolPorts[protocolStr] + calicoPorts = SimplifyPorts(calicoPorts) + + var protocol *numorstring.Protocol + if protocolStr != "" { + p := numorstring.ProtocolFromString(protocolStr) + protocol = &p + } + + // Based on specifications at least one Peer is set. + var selector, nsSelector string + for _, peer := range rule.From { + var found bool + if peer.Namespaces != nil { + selector = "" + nsSelector = k8sSelectorToCalico(peer.Namespaces, SelectorNamespace) + found = true + } + if peer.Pods != nil { + selector = k8sSelectorToCalico(&peer.Pods.PodSelector, SelectorPod) + nsSelector = k8sSelectorToCalico(&peer.Pods.NamespaceSelector, SelectorNamespace) + found = true + } + if !found { + return nil, fmt.Errorf("none of supported fields in 'From' is set.") + } + + // Build inbound rule and append to list. + rules = append(rules, apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata(rule.Name), + Action: action, + Protocol: protocol, + Source: apiv3.EntityRule{ + Selector: selector, + NamespaceSelector: nsSelector, + }, + Destination: apiv3.EntityRule{ + Ports: calicoPorts, + }, + }) + } + } + + return rules, nil +} + +func k8sANPEgressRuleToCalico(rule adminpolicy.AdminNetworkPolicyEgressRule) ([]apiv3.Rule, error) { + rules := []apiv3.Rule{} + + action, err := K8sAdminNetworkPolicyActionToCalico(rule.Action) + if err != nil { + return nil, err + } + + // If there no ports, represent that as zero struct. + ports := []adminpolicy.AdminNetworkPolicyPort{{}} + if rule.Ports != nil && len(*rule.Ports) != 0 { + ports = *rule.Ports + } + + protocolPorts := map[string][]numorstring.Port{} + + for _, port := range ports { + protocol, calicoPort, err := k8sAdminPolicyPortToCalicoFields(&port) + if err != nil { + return nil, fmt.Errorf("failed to parse k8s port: %s", err) + } + + if protocol == nil && calicoPort == nil { + // If nil, no ports were specified, or an empty port struct was provided, which we translate to allowing all. + // We want to use a nil protocol and a nil list of ports, which will allow any destination (for ingress). + // Given we're gonna allow all, we may as well break here and keep only this rule + protocolPorts = map[string][]numorstring.Port{"": nil} + break + } + + pStr := protocol.String() + // treat nil as 'all ports' + if calicoPort == nil { + protocolPorts[pStr] = nil + } else if _, ok := protocolPorts[pStr]; !ok || len(protocolPorts[pStr]) > 0 { + // don't overwrite a nil (allow all ports) if present; if no ports yet for this protocol + // or 1+ ports which aren't 'all ports', then add the present ports + protocolPorts[pStr] = append(protocolPorts[pStr], *calicoPort) + } + } + + protocols := make([]string, 0, len(protocolPorts)) + for k := range protocolPorts { + protocols = append(protocols, k) + } + // Ensure deterministic output + sort.Strings(protocols) + + // Combine destinations with sources to generate rules. We generate one rule per protocol, + // with each rule containing all the allowed ports. + for _, protocolStr := range protocols { + calicoPorts := protocolPorts[protocolStr] + calicoPorts = SimplifyPorts(calicoPorts) + + var protocol *numorstring.Protocol + if protocolStr != "" { + p := numorstring.ProtocolFromString(protocolStr) + protocol = &p + } + + // Based on specifications at least one Peer is set. + var selector, nsSelector string + for _, peer := range rule.To { + var found bool + if peer.Namespaces != nil { + selector = "" + nsSelector = k8sSelectorToCalico(peer.Namespaces, SelectorNamespace) + found = true + } + if peer.Pods != nil { + selector = k8sSelectorToCalico(&peer.Pods.PodSelector, SelectorPod) + nsSelector = k8sSelectorToCalico(&peer.Pods.NamespaceSelector, SelectorNamespace) + found = true + } + if !found { + return nil, fmt.Errorf("none of supported fields in 'To' is set.") + } + + // Build outbound rule and append to list. + rules = append(rules, apiv3.Rule{ + Metadata: k8sAdminNetworkPolicyToCalicoMetadata(rule.Name), + Action: action, + Protocol: protocol, + Destination: apiv3.EntityRule{ + Ports: calicoPorts, + Selector: selector, + NamespaceSelector: nsSelector, + }, + }) + } + } + + return rules, nil +} + +func K8sAdminNetworkPolicyActionToCalico(action adminpolicy.AdminNetworkPolicyRuleAction) (apiv3.Action, error) { + switch action { + case adminpolicy.AdminNetworkPolicyRuleActionAllow, + adminpolicy.AdminNetworkPolicyRuleActionDeny, + adminpolicy.AdminNetworkPolicyRuleActionPass: + return apiv3.Action(action), nil + default: + return "", fmt.Errorf("unsupported admin network policy action %v", action) + } +} + +func k8sAdminNetworkPolicyToCalicoMetadata(ruleName string) *apiv3.RuleMetadata { + if ruleName == "" { + return nil + } + return &apiv3.RuleMetadata{ + Annotations: map[string]string{ + AdminPolicyRuleNameLabel: ruleName, + }, + } +} + +func ensureProtocol(proto kapiv1.Protocol) kapiv1.Protocol { + if proto != "" { + return proto + } + return kapiv1.ProtocolTCP +} + +func k8sAdminPolicyPortToCalicoFields(port *adminpolicy.AdminNetworkPolicyPort) ( + protocol *numorstring.Protocol, + dstPort *numorstring.Port, + err error, +) { + // If no port info, return zero values for all fields (protocol, dstPorts). + if port == nil { + return + } + // Only one of the PortNumber or PortRange is set. + if port.PortNumber != nil { + dstPort = k8sAdminPolicyPortToCalico(port.PortNumber) + proto := ensureProtocol(port.PortNumber.Protocol) + protocol = k8sProtocolToCalico(&proto) + return + } + if port.PortRange != nil { + dstPort, err = k8sAdminPolicyPortRangeToCalico(port.PortRange) + if err != nil { + return + } + proto := ensureProtocol(port.PortRange.Protocol) + protocol = k8sProtocolToCalico(&proto) + return + } + // TODO: Add support for NamedPorts + return +} + +func k8sAdminPolicyPortToCalico(port *adminpolicy.Port) *numorstring.Port { + if port == nil { + return nil + } + p := numorstring.SinglePort(uint16(port.Port)) + return &p +} + +func k8sAdminPolicyPortRangeToCalico(port *adminpolicy.PortRange) (*numorstring.Port, error) { + if port == nil { + return nil, nil + } + p, err := numorstring.PortFromRange(uint16(port.Start), uint16(port.End)) + if err != nil { + return nil, err + } + return &p, nil +} + // K8sNetworkPolicyToCalico converts a k8s NetworkPolicy to a model.KVPair. func (c converter) K8sNetworkPolicyToCalico(np *networkingv1.NetworkPolicy) (*model.KVPair, error) { // Pull out important fields. - policyName := fmt.Sprintf(K8sNetworkPolicyNamePrefix + np.Name) + policyName := names.K8sNetworkPolicyNamePrefix + np.Name // We insert all the NetworkPolicy Policies at order 1000.0 after conversion. // This order might change in future. @@ -287,7 +670,7 @@ func (c converter) K8sNetworkPolicyToCalico(np *networkingv1.NetworkPolicy) (*mo // Generate the ingress rules list. var ingressRules []apiv3.Rule for _, r := range np.Spec.Ingress { - rules, err := c.k8sRuleToCalico(r.From, r.Ports, np.Namespace, true) + rules, err := c.k8sRuleToCalico(r.From, r.Ports, true) if err != nil { log.WithError(err).Warn("dropping k8s rule that couldn't be converted.") // Add rule to conversion error slice @@ -300,7 +683,7 @@ func (c converter) K8sNetworkPolicyToCalico(np *networkingv1.NetworkPolicy) (*mo // Generate the egress rules list. var egressRules []apiv3.Rule for _, r := range np.Spec.Egress { - rules, err := c.k8sRuleToCalico(r.To, r.Ports, np.Namespace, false) + rules, err := c.k8sRuleToCalico(r.To, r.Ports, false) if err != nil { log.WithError(err).Warn("dropping k8s rule that couldn't be converted") // Add rule to conversion error slice @@ -361,7 +744,7 @@ func (c converter) K8sNetworkPolicyToCalico(np *networkingv1.NetworkPolicy) (*mo } policy.Spec = apiv3.NetworkPolicySpec{ Order: &order, - Selector: c.k8sSelectorToCalico(&np.Spec.PodSelector, SelectorPod), + Selector: k8sSelectorToCalico(&np.Spec.PodSelector, SelectorPod), Ingress: ingressRules, Egress: egressRules, Types: policyTypes, @@ -384,7 +767,7 @@ func (c converter) K8sNetworkPolicyToCalico(np *networkingv1.NetworkPolicy) (*mo // k8sSelectorToCalico takes a namespaced k8s label selector and returns the Calico // equivalent. -func (c converter) k8sSelectorToCalico(s *metav1.LabelSelector, selectorType selectorType) string { +func k8sSelectorToCalico(s *metav1.LabelSelector, selectorType selectorType) string { // Only prefix pod selectors - this won't work for namespace selectors. selectors := []string{} if selectorType == SelectorPod { @@ -434,7 +817,7 @@ func (c converter) k8sSelectorToCalico(s *metav1.LabelSelector, selectorType sel return strings.Join(selectors, " && ") } -func (c converter) k8sRuleToCalico(rPeers []networkingv1.NetworkPolicyPeer, rPorts []networkingv1.NetworkPolicyPort, ns string, ingress bool) ([]apiv3.Rule, error) { +func (c converter) k8sRuleToCalico(rPeers []networkingv1.NetworkPolicyPeer, rPorts []networkingv1.NetworkPolicyPort, ingress bool) ([]apiv3.Rule, error) { rules := []apiv3.Rule{} peers := []*networkingv1.NetworkPolicyPeer{} ports := []*networkingv1.NetworkPolicyPort{} @@ -528,7 +911,7 @@ func (c converter) k8sRuleToCalico(rPeers []networkingv1.NetworkPolicyPeer, rPor } for _, peer := range peers { - selector, nsSelector, nets, notNets := c.k8sPeerToCalicoFields(peer, ns) + selector, nsSelector, nets, notNets := c.k8sPeerToCalicoFields(peer) if ingress { // Build inbound rule and append to list. rules = append(rules, apiv3.Rule{ @@ -643,11 +1026,11 @@ func (c converter) k8sPortToCalicoFields(port *networkingv1.NetworkPolicyPort) ( if err != nil { return } - protocol = c.k8sProtocolToCalico(port.Protocol) + protocol = k8sProtocolToCalico(port.Protocol) return } -func (c converter) k8sProtocolToCalico(protocol *kapiv1.Protocol) *numorstring.Protocol { +func k8sProtocolToCalico(protocol *kapiv1.Protocol) *numorstring.Protocol { if protocol != nil { p := numorstring.ProtocolFromString(string(*protocol)) return &p @@ -655,7 +1038,7 @@ func (c converter) k8sProtocolToCalico(protocol *kapiv1.Protocol) *numorstring.P return nil } -func (c converter) k8sPeerToCalicoFields(peer *networkingv1.NetworkPolicyPeer, ns string) (selector, nsSelector string, nets []string, notNets []string) { +func (c converter) k8sPeerToCalicoFields(peer *networkingv1.NetworkPolicyPeer) (selector, nsSelector string, nets []string, notNets []string) { // If no peer, return zero values for all fields (selector, nets and !nets). if peer == nil { return @@ -686,8 +1069,8 @@ func (c converter) k8sPeerToCalicoFields(peer *networkingv1.NetworkPolicyPeer, n // IPBlock is not set to get here. // Note that k8sSelectorToCalico() accepts nil values of the selector. - selector = c.k8sSelectorToCalico(peer.PodSelector, SelectorPod) - nsSelector = c.k8sSelectorToCalico(peer.NamespaceSelector, SelectorNamespace) + selector = k8sSelectorToCalico(peer.PodSelector, SelectorPod) + nsSelector = k8sSelectorToCalico(peer.NamespaceSelector, SelectorNamespace) return } diff --git a/libcalico-go/lib/backend/k8s/conversion/conversion_test.go b/libcalico-go/lib/backend/k8s/conversion/conversion_test.go index b485d60275b..a1dbf53d03c 100644 --- a/libcalico-go/lib/backend/k8s/conversion/conversion_test.go +++ b/libcalico-go/lib/backend/k8s/conversion/conversion_test.go @@ -111,9 +111,7 @@ var _ = Describe("Test selector conversion", func() { DescribeTable("selector conversion table", func(inSelector *metav1.LabelSelector, selectorType selectorType, expected string) { // First, convert the NetworkPolicy using the k8s conversion logic. - c := converter{} - - converted := c.k8sSelectorToCalico(inSelector, selectorType) + converted := k8sSelectorToCalico(inSelector, selectorType) // Finally, assert the expected result. Expect(converted).To(Equal(expected)) @@ -2699,7 +2697,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() { } // Parse the policy. - podSel, nsSel, nets, notNets := c.(*converter).k8sPeerToCalicoFields(&np, "default") + podSel, nsSel, nets, notNets := c.(*converter).k8sPeerToCalicoFields(&np) // Assert value fields are correct. Expect(nets[0]).To(Equal("192.168.0.0/16")) @@ -2718,7 +2716,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() { } // Parse the policy. - podSel, nsSel, nets, notNets := c.(*converter).k8sPeerToCalicoFields(&np, "default") + podSel, nsSel, nets, notNets := c.(*converter).k8sPeerToCalicoFields(&np) // Assert value fields are correct. Expect(nets).To(BeNil()) @@ -2738,7 +2736,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() { } // Parse the policy. - podSel, nsSel, nets, notNets := c.(*converter).k8sPeerToCalicoFields(&np, "default") + podSel, nsSel, nets, notNets := c.(*converter).k8sPeerToCalicoFields(&np) // Assert value fields are correct. Expect(nets[0]).To(Equal("192.168.0.0/16")) diff --git a/libcalico-go/lib/backend/k8s/k8s.go b/libcalico-go/lib/backend/k8s/k8s.go index d83b78e5edd..40ee065f727 100644 --- a/libcalico-go/lib/backend/k8s/k8s.go +++ b/libcalico-go/lib/backend/k8s/k8s.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + adminpolicyclient "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned/typed/apis/v1alpha1" ) var ( @@ -61,6 +62,9 @@ type KubeClient struct { // Client for interacting with CustomResourceDefinition. crdClientV1 *rest.RESTClient + // Client for interacting with K8S Admin Network Policy, and BaselineAdminNetworkPolicy. + k8sAdminPolicyClient *adminpolicyclient.PolicyV1alpha1Client + disableNodePoll bool // Contains methods for converting Kubernetes resources to @@ -88,9 +92,15 @@ func NewKubeClient(ca *apiconfig.CalicoAPIConfigSpec) (api.Client, error) { return nil, fmt.Errorf("Failed to build V1 CRD client: %v", err) } + k8sAdminPolicyClient, err := buildK8SAdminPolicyClient(config) + if err != nil { + return nil, fmt.Errorf("Failed to build K8S Admin Network Policy client: %v", err) + } + kubeClient := &KubeClient{ ClientSet: cs, crdClientV1: crdClientV1, + k8sAdminPolicyClient: k8sAdminPolicyClient, disableNodePoll: ca.K8sDisableNodePoll, clientsByResourceKind: make(map[string]resources.K8sResourceClient), clientsByKeyType: make(map[reflect.Type]resources.K8sResourceClient), @@ -116,6 +126,12 @@ func NewKubeClient(ca *apiconfig.CalicoAPIConfigSpec) (api.Client, error) { apiv3.KindGlobalNetworkPolicy, resources.NewGlobalNetworkPolicyClient(cs, crdClientV1), ) + kubeClient.registerResourceClient( + reflect.TypeOf(model.ResourceKey{}), + reflect.TypeOf(model.ResourceListOptions{}), + model.KindKubernetesAdminNetworkPolicy, + resources.NewKubernetesAdminNetworkPolicyClient(k8sAdminPolicyClient), + ) kubeClient.registerResourceClient( reflect.TypeOf(model.ResourceKey{}), reflect.TypeOf(model.ResourceListOptions{}), @@ -146,6 +162,12 @@ func NewKubeClient(ca *apiconfig.CalicoAPIConfigSpec) (api.Client, error) { apiv3.KindNetworkSet, resources.NewNetworkSetClient(cs, crdClientV1), ) + kubeClient.registerResourceClient( + reflect.TypeOf(model.ResourceKey{}), + reflect.TypeOf(model.ResourceListOptions{}), + apiv3.KindTier, + resources.NewTierClient(cs, crdClientV1), + ) kubeClient.registerResourceClient( reflect.TypeOf(model.ResourceKey{}), reflect.TypeOf(model.ResourceListOptions{}), @@ -423,6 +445,7 @@ func (c *KubeClient) Clean() error { apiv3.KindFelixConfiguration, apiv3.KindGlobalNetworkPolicy, apiv3.KindNetworkPolicy, + apiv3.KindTier, apiv3.KindGlobalNetworkSet, apiv3.KindNetworkSet, apiv3.KindIPPool, @@ -493,6 +516,11 @@ func (c *KubeClient) Close() error { var addToSchemeOnce sync.Once +// buildK8SAdminPolicyClient builds a RESTClient configured to interact (Baseline) Admin Network Policy. +func buildK8SAdminPolicyClient(cfg *rest.Config) (*adminpolicyclient.PolicyV1alpha1Client, error) { + return adminpolicyclient.NewForConfig(cfg) +} + // buildCRDClientV1 builds a RESTClient configured to interact with Calico CustomResourceDefinitions func buildCRDClientV1(cfg rest.Config) (*rest.RESTClient, error) { // Generate config using the base config. @@ -539,6 +567,8 @@ func buildCRDClientV1(cfg rest.Config) (*rest.RESTClient, error) { &apiv3.NetworkPolicyList{}, &apiv3.NetworkSet{}, &apiv3.NetworkSetList{}, + &apiv3.Tier{}, + &apiv3.TierList{}, &apiv3.HostEndpoint{}, &apiv3.HostEndpointList{}, &libapiv3.BlockAffinity{}, diff --git a/libcalico-go/lib/backend/k8s/k8s_test.go b/libcalico-go/lib/backend/k8s/k8s_test.go index afe85d34a5c..67a11feb2af 100644 --- a/libcalico-go/lib/backend/k8s/k8s_test.go +++ b/libcalico-go/lib/backend/k8s/k8s_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,9 +31,12 @@ import ( k8sapi "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" + adminpolicy "sigs.k8s.io/network-policy-api/apis/v1alpha1" + adminpolicyclient "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned/typed/apis/v1alpha1" apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/api/pkg/lib/numorstring" @@ -448,6 +451,7 @@ var _ = testutils.E2eDatastoreDescribe("Test UIDs and owner references", testuti var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", testutils.DatastoreK8s, func(cfg apiconfig.CalicoAPIConfig) { var ( c *KubeClient + cli ctrlclient.Client cb *cb syncer api.Syncer ) @@ -458,8 +462,15 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", log.SetLevel(log.DebugLevel) // Create a Kubernetes client, callbacks, and a syncer. - cfg := apiconfig.KubeConfig{Kubeconfig: "/kubeconfig.yaml"} - c, cb, syncer = CreateClientAndSyncer(cfg) + apicfg := apiconfig.KubeConfig{Kubeconfig: "/kubeconfig.yaml"} + c, cb, syncer = CreateClientAndSyncer(apicfg) + + // Create a controller-runtime client. + // Create a client for interacting with CRDs directly. + config, _, err := CreateKubernetesClientset(&cfg.Spec) + Expect(err).NotTo(HaveOccurred()) + config.ContentType = runtime.ContentTypeJSON + cli, err = ctrlclient.New(config, ctrlclient.Options{}) // Start the syncer. syncer.Start() @@ -543,8 +554,8 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", By("Checking the correct entries are in our cache", func() { expectedName := "kns.test-syncer-namespace-default-deny" - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{expectedName}})).Should(BeTrue()) - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{expectedName}})).Should(BeTrue()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: expectedName}})).Should(BeTrue()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{Name: expectedName}})).Should(BeTrue()) }) By("Deleting the namespace", func() { @@ -553,8 +564,8 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", By("Checking the correct entries are no longer in our cache", func() { expectedName := "kns.test-syncer-namespace-default-deny" - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{expectedName}}), slowCheck...).Should(BeFalse()) - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{expectedName}})).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: expectedName}}), slowCheck...).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{Name: expectedName}})).Should(BeFalse()) }) }) @@ -593,8 +604,8 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", // Expect corresponding Profile updates over the syncer for this Namespace. By("Checking the correct entries are in our cache", func() { expectedName := "kns.test-syncer-namespace-no-default-deny" - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{expectedName}})).Should(BeTrue()) - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{expectedName}})).Should(BeTrue()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: expectedName}})).Should(BeTrue()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{Name: expectedName}})).Should(BeTrue()) }) By("deleting a namespace", func() { @@ -603,8 +614,8 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", By("Checking the correct entries are in no longer in our cache", func() { expectedName := "kns.test-syncer-namespace-no-default-deny" - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{expectedName}}), slowCheck...).Should(BeFalse()) - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{expectedName}})).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: expectedName}}), slowCheck...).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileLabelsKey{ProfileKey: model.ProfileKey{Name: expectedName}})).Should(BeFalse()) }) }) @@ -633,7 +644,7 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", By("existing in our cache", func() { expectedName := "projectcalico-default-allow" - Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{expectedName}}), slowCheck...).Should(BeTrue()) + Eventually(cb.GetSyncerValuePresentFunc(model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: expectedName}}), slowCheck...).Should(BeTrue()) }) By("watching all profiles with a valid rv does not return an event for the default-allow profile", func() { @@ -765,12 +776,278 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", Expect(err).To(HaveOccurred()) }) + It("should handle a CRUD of Tiers", func() { + var kvpRes *model.KVPair + + order30 := 30.0 + order40 := 40.0 + defaultOrder := apiv3.DefaultTierOrder + + actionPass := apiv3.Pass + actionDeny := apiv3.Deny + + tierWithOder30 := model.Tier{ + Order: &order30, + DefaultAction: apiv3.Pass, + } + tierWithOrder40 := model.Tier{ + Order: &order40, + DefaultAction: apiv3.Deny, + } + tierWithDefaultOrder := model.Tier{ + Order: &defaultOrder, + DefaultAction: apiv3.Deny, + } + + tierClient := c.GetResourceClientFromResourceKind(apiv3.KindTier) + kvp1Name := "security-tier" + kvp1KeyV1 := model.TierKey{Name: kvp1Name} + kvp1a := &model.KVPair{ + Key: model.ResourceKey{Name: kvp1Name, Kind: apiv3.KindTier}, + Value: &apiv3.Tier{ + TypeMeta: metav1.TypeMeta{ + Kind: apiv3.KindTier, + APIVersion: apiv3.GroupVersionCurrent, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: kvp1Name, + }, + Spec: apiv3.TierSpec{}, + }, + } + + kvp1b := &model.KVPair{ + Key: model.ResourceKey{Name: kvp1Name, Kind: apiv3.KindTier}, + Value: &apiv3.Tier{ + TypeMeta: metav1.TypeMeta{ + Kind: apiv3.KindTier, + APIVersion: apiv3.GroupVersionCurrent, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: kvp1Name, + }, + Spec: apiv3.TierSpec{ + Order: &order30, + DefaultAction: &actionPass, + }, + }, + } + + kvp2Name := "platform-tier" + kvp2KeyV1 := model.TierKey{Name: kvp2Name} + kvp2a := &model.KVPair{ + Key: model.ResourceKey{Name: kvp2Name, Kind: apiv3.KindTier}, + Value: &apiv3.Tier{ + TypeMeta: metav1.TypeMeta{ + Kind: apiv3.KindTier, + APIVersion: apiv3.GroupVersionCurrent, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: kvp2Name, + }, + Spec: apiv3.TierSpec{ + Order: &order40, + }, + }, + } + + kvp2b := &model.KVPair{ + Key: model.ResourceKey{Name: kvp2Name, Kind: apiv3.KindTier}, + Value: &apiv3.Tier{ + TypeMeta: metav1.TypeMeta{ + Kind: apiv3.KindTier, + APIVersion: apiv3.GroupVersionCurrent, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: kvp2Name, + }, + Spec: apiv3.TierSpec{}, + }, + } + + kvp3Name := "legacy-tier" + kvp3KeyV1 := model.TierKey{Name: kvp3Name} + kvp3 := &model.KVPair{ + Key: model.ResourceKey{Name: kvp3Name, Kind: apiv3.KindTier}, + Value: &apiv3.Tier{ + TypeMeta: metav1.TypeMeta{ + Kind: apiv3.KindTier, + APIVersion: apiv3.GroupVersionCurrent, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: kvp3Name, + }, + Spec: apiv3.TierSpec{ + Order: &defaultOrder, + DefaultAction: &actionDeny, + }, + }, + } + + // Check our syncer has the correct Tier entries for the two + // System Network Protocols that this test manipulates. Neither + // have been created yet. + By("Checking cache does not have Tier entries", func() { + Eventually(cb.GetSyncerValuePresentFunc(kvp1KeyV1)).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(kvp2KeyV1)).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(kvp3KeyV1)).Should(BeFalse()) + }) + + By("Reading an existing tier with nil order", func() { + // Create a tier with nil order + crd := &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{ + Name: kvp3Name, + }, + Spec: apiv3.TierSpec{}, + } + err := cli.Create(ctx, crd) + Expect(err).NotTo(HaveOccurred()) + + // Reading it back, and it should still return nil order + err = cli.Get(ctx, types.NamespacedName{Name: kvp3Name}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Name).To(Equal(kvp3Name)) + Expect(crd.Spec.Order).To(BeNil()) + + // Reading it back using Calico k8s backend client, should return the default order value + kvp, err := c.Get(ctx, model.ResourceKey{Name: kvp3Name, Kind: apiv3.KindTier}, "") + Expect(err).ToNot(HaveOccurred()) + t := kvp.Value.(*apiv3.Tier) + Expect(t.Name).To(Equal(kvp3Name)) + Expect(*t.Spec.Order).To(Equal(apiv3.DefaultTierOrder)) + Expect(*t.Spec.DefaultAction).To(Equal(apiv3.Deny)) + }) + + By("Creating a Tier", func() { + var err error + kvpRes, err = tierClient.Create(ctx, kvp1a) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Checking cache has correct Tier entries", func() { + Eventually(cb.GetSyncerValueFunc(kvp1KeyV1)).Should(Equal(&tierWithDefaultOrder)) + Eventually(cb.GetSyncerValuePresentFunc(kvp2KeyV1)).Should(BeFalse()) + Eventually(cb.GetSyncerValueFunc(kvp3KeyV1)).Should(Equal(&tierWithDefaultOrder)) + }) + + By("Attempting to recreate an existing Tier", func() { + _, err := tierClient.Create(ctx, kvp1a) + Expect(err).To(HaveOccurred()) + }) + + By("Updating an existing Tier", func() { + kvp1b.Revision = kvpRes.Revision + _, err := tierClient.Update(ctx, kvp1b) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Checking cache has correct Tier entries", func() { + Eventually(cb.GetSyncerValueFunc(kvp1KeyV1)).Should(Equal(&tierWithOder30)) + Eventually(cb.GetSyncerValuePresentFunc(kvp2a.Key)).Should(BeFalse()) + }) + + By("Create another Tier", func() { + var err error + kvpRes, err = tierClient.Create(ctx, kvp2a) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Checking cache has correct Tier entries", func() { + Eventually(cb.GetSyncerValueFunc(kvp1KeyV1)).Should(Equal(&tierWithOder30)) + Eventually(cb.GetSyncerValueFunc(kvp2KeyV1)).Should(Equal(&tierWithOrder40)) + Eventually(cb.GetSyncerValueFunc(kvp3KeyV1)).Should(Equal(&tierWithDefaultOrder)) + }) + + By("Updating the Tier created by Create", func() { + kvp2b.Revision = kvpRes.Revision + _, err := tierClient.Update(ctx, kvp2b) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Checking cache has correct Tier entries", func() { + Eventually(cb.GetSyncerValueFunc(kvp1KeyV1)).Should(Equal(&tierWithOder30)) + Eventually(cb.GetSyncerValueFunc(kvp2KeyV1)).Should(Equal(&tierWithDefaultOrder)) + Eventually(cb.GetSyncerValueFunc(kvp3KeyV1)).Should(Equal(&tierWithDefaultOrder)) + }) + + By("Deleted the Tier created by Apply", func() { + _, err := tierClient.Delete(ctx, kvp2a.Key, "", nil) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Checking cache has correct Tier entries", func() { + Eventually(cb.GetSyncerValueFunc(kvp1KeyV1)).Should(Equal(&tierWithOder30)) + Eventually(cb.GetSyncerValuePresentFunc(kvp2KeyV1)).Should(BeFalse()) + Eventually(cb.GetSyncerValueFunc(kvp3KeyV1)).Should(Equal(&tierWithDefaultOrder)) + }) + + By("Getting a Tier that does not exist", func() { + _, err := c.Get(ctx, model.ResourceKey{Name: "my-nonexistent-test-tier", Kind: apiv3.KindTier}, "") + Expect(err).To(HaveOccurred()) + }) + + By("Listing a missing Tier", func() { + kvps, err := c.List(ctx, model.ResourceListOptions{Name: "my-nonexistent-test-tier", Kind: apiv3.KindTier}, "") + Expect(err).ToNot(HaveOccurred()) + Expect(kvps.KVPairs).To(HaveLen(0)) + }) + + By("Getting an existing Tier", func() { + kvp, err := c.Get(ctx, model.ResourceKey{Name: "security-tier", Kind: apiv3.KindTier}, "") + Expect(err).ToNot(HaveOccurred()) + Expect(kvp.Key.(model.ResourceKey).Name).To(Equal("security-tier")) + Expect(kvp.Value.(*apiv3.Tier).Spec).To(Equal(kvp1b.Value.(*apiv3.Tier).Spec)) + }) + + latestRevision := "" + By("Listing all Tiers", func() { + kvps, err := c.List(ctx, model.ResourceListOptions{Kind: apiv3.KindTier}, "") + Expect(err).ToNot(HaveOccurred()) + Expect(kvps.KVPairs).To(HaveLen(2)) + Expect(kvps.KVPairs[len(kvps.KVPairs)-2].Key.(model.ResourceKey).Name).To(Equal("legacy-tier")) + Expect(kvps.KVPairs[len(kvps.KVPairs)-2].Value.(*apiv3.Tier).Spec).To(Equal(kvp3.Value.(*apiv3.Tier).Spec)) + Expect(kvps.KVPairs[len(kvps.KVPairs)-1].Key.(model.ResourceKey).Name).To(Equal("security-tier")) + Expect(kvps.KVPairs[len(kvps.KVPairs)-1].Value.(*apiv3.Tier).Spec).To(Equal(kvp1b.Value.(*apiv3.Tier).Spec)) + latestRevision = kvps.Revision + }) + + By("Listing all Tiers, using an invalid revision", func() { + _, err := c.List(ctx, model.ResourceListOptions{Kind: apiv3.KindTier}, fmt.Sprintf("1%s", kvp2b.Revision)) + Expect(err).To(HaveOccurred()) + }) + + By("Listing all Tiers with a valid revision", func() { + Expect(latestRevision).NotTo(Equal("")) + kvps, err := c.List(ctx, model.ResourceListOptions{Kind: apiv3.KindTier}, latestRevision) + Expect(err).ToNot(HaveOccurred()) + Expect(kvps.KVPairs).To(HaveLen(2)) + Expect(kvps.KVPairs[len(kvps.KVPairs)-2].Key.(model.ResourceKey).Name).To(Equal("legacy-tier")) + Expect(kvps.KVPairs[len(kvps.KVPairs)-2].Value.(*apiv3.Tier).Spec).To(Equal(kvp3.Value.(*apiv3.Tier).Spec)) + Expect(kvps.KVPairs[len(kvps.KVPairs)-1].Key.(model.ResourceKey).Name).To(Equal("security-tier")) + Expect(kvps.KVPairs[len(kvps.KVPairs)-1].Value.(*apiv3.Tier).Spec).To(Equal(kvp1b.Value.(*apiv3.Tier).Spec)) + }) + + By("Deleting all existing Tiers", func() { + _, err := tierClient.Delete(ctx, kvp1a.Key, "", nil) + Expect(err).NotTo(HaveOccurred()) + _, err = tierClient.Delete(ctx, kvp3.Key, "", nil) + Expect(err).NotTo(HaveOccurred()) + }) + + By("Checking cache has no Tier entries", func() { + Eventually(cb.GetSyncerValuePresentFunc(kvp1KeyV1)).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(kvp2KeyV1)).Should(BeFalse()) + Eventually(cb.GetSyncerValuePresentFunc(kvp3KeyV1)).Should(BeFalse()) + }) + }) + It("should handle a CRUD of Global Network Policy", func() { var kvpRes *model.KVPair gnpClient := c.GetResourceClientFromResourceKind(apiv3.KindGlobalNetworkPolicy) kvp1Name := "my-test-gnp" - kvp1KeyV1 := model.PolicyKey{Name: kvp1Name} + kvp1KeyV1 := model.PolicyKey{Name: kvp1Name, Tier: "default"} kvp1a := &model.KVPair{ Key: model.ResourceKey{Name: kvp1Name, Kind: apiv3.KindGlobalNetworkPolicy}, Value: &apiv3.GlobalNetworkPolicy{ @@ -800,7 +1077,7 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", } kvp2Name := "my-test-gnp2" - kvp2KeyV1 := model.PolicyKey{Name: kvp2Name} + kvp2KeyV1 := model.PolicyKey{Name: kvp2Name, Tier: "default"} kvp2a := &model.KVPair{ Key: model.ResourceKey{Name: kvp2Name, Kind: apiv3.KindGlobalNetworkPolicy}, Value: &apiv3.GlobalNetworkPolicy{ @@ -2416,7 +2693,7 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", By("Syncing HostIPs over the Syncer", func() { expectExist := []api.Update{ - {model.KVPair{Key: model.HostIPKey{Hostname: nodeHostname}}, api.UpdateTypeKVUpdated}, + {KVPair: model.KVPair{Key: model.HostIPKey{Hostname: nodeHostname}}, UpdateType: api.UpdateTypeKVUpdated}, } // Expect the snapshot to include the right keys. @@ -2453,7 +2730,7 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", } expectedKeys := []api.Update{ - {hostConfigKey, api.UpdateTypeKVNew}, + {KVPair: hostConfigKey, UpdateType: api.UpdateTypeKVNew}, } snapshotCallbacks.ExpectExists(expectedKeys) @@ -2463,8 +2740,9 @@ var _ = testutils.E2eDatastoreDescribe("Test Syncer API for Kubernetes backend", var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.DatastoreK8s, func(cfg apiconfig.CalicoAPIConfig) { var ( - c *KubeClient - ctx context.Context + c *KubeClient + anpClient *adminpolicyclient.PolicyV1alpha1Client + ctx context.Context ) BeforeEach(func() { @@ -2473,6 +2751,12 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore Expect(err).NotTo(HaveOccurred()) c = client.(*KubeClient) + config, _, err := CreateKubernetesClientset(&cfg.Spec) + Expect(err).NotTo(HaveOccurred()) + config.ContentType = runtime.ContentTypeJSON + anpClient, err = buildK8SAdminPolicyClient(config) + Expect(err).NotTo(HaveOccurred()) + ctx = context.Background() }) @@ -2525,6 +2809,69 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore }) }) + Describe("watching AdminNetworkPolicies", func() { + createTestAdminNetworkPolicy := func(name string) { + anp := &adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 100, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + } + _, err := anpClient.AdminNetworkPolicies().Create(ctx, anp, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + } + deleteAllAdminNetworkPolicies := func() { + var zero int64 + err := anpClient.AdminNetworkPolicies().DeleteCollection( + ctx, + metav1.DeleteOptions{GracePeriodSeconds: &zero}, + metav1.ListOptions{}, + ) + Expect(err).NotTo(HaveOccurred()) + } + BeforeEach(func() { + createTestAdminNetworkPolicy("test-admin-net-policy-1") + createTestAdminNetworkPolicy("test-admin-net-policy-2") + }) + AfterEach(func() { + deleteAllAdminNetworkPolicies() + }) + It("supports watching all adminnetworkpolicies", func() { + watch, err := c.Watch(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, "") + Expect(err).NotTo(HaveOccurred()) + defer watch.Stop() + ExpectAddedEvent(watch.ResultChan()) + }) + It("supports resuming watch from previous revision", func() { + watch, err := c.Watch(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, "") + Expect(err).NotTo(HaveOccurred()) + event := ExpectAddedEvent(watch.ResultChan()) + watch.Stop() + + watch, err = c.Watch(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, event.New.Revision) + Expect(err).NotTo(HaveOccurred()) + watch.Stop() + }) + It("should handle a list for many network policies with a revision", func() { + for i := 3; i < 1000; i++ { + createTestAdminNetworkPolicy(fmt.Sprintf("test-admin-net-policy-%d", i)) + } + kvs, err := c.List(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, "") + Expect(err).NotTo(HaveOccurred()) + _, err = c.List(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, kvs.Revision) + Expect(err).NotTo(HaveOccurred()) + }) + }) + Describe("watching NetworkPolicies (native)", func() { createTestNetworkPolicy := func(name string) { np := networkingv1.NetworkPolicy{ @@ -2627,7 +2974,35 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore }) }) - Describe("watching / listing network polices (k8s and Calico)", func() { + Describe("watching / listing network polices (k8s and Calico) and admin network policies", func() { + createTestAdminNetworkPolicy := func(name string) { + anp := &adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Priority: 100, + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "value", + }, + }, + }, + }, + } + _, err := anpClient.AdminNetworkPolicies().Create(ctx, anp, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + } + deleteAllAdminNetworkPolicies := func() { + var zero int64 + err := anpClient.AdminNetworkPolicies().DeleteCollection( + ctx, + metav1.DeleteOptions{GracePeriodSeconds: &zero}, + metav1.ListOptions{}, + ) + Expect(err).NotTo(HaveOccurred()) + } createCalicoNetworkPolicy := func(name string) { np := &model.KVPair{ Key: model.ResourceKey{ @@ -2666,7 +3041,9 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore Expect(err).NotTo(HaveOccurred()) } BeforeEach(func() { - // Create 2x Calico NP and 2x k8s NP + // Create 2x Calico NP and 2x k8s NP and 2x k8s ANP + createTestAdminNetworkPolicy("test-admin-net-policy-1") + createTestAdminNetworkPolicy("test-admin-net-policy-2") createCalicoNetworkPolicy("test-net-policy-1") createCalicoNetworkPolicy("test-net-policy-2") createK8sNetworkPolicy("test-net-policy-3") @@ -2676,6 +3053,7 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore AfterEach(func() { log.Info("[Test] Beginning Cleanup ----") deleteAllNetworkPolicies() + deleteAllAdminNetworkPolicies() }) It("supports resuming watch from previous revision (calico)", func() { @@ -2804,6 +3182,72 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore watch.Stop() }) + It("supports resuming watch from previous revision k8s admin network policy", func() { + // Should only return k8s ANPs + l, err := c.List(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, "") + Expect(err).NotTo(HaveOccurred()) + Expect(l.KVPairs).To(HaveLen(2)) + + // Now, modify all the policies. It's important to do this with + // multiple policies of each type, because we want to test that revision + // numbers come out in a sensible order. We're going to resume the watch + // from the "last" event to come out of the watch, and if it doesn't + // really represent the latest update, when we resume watching, we + // will get duplicate events. Worse, if the "last" event from a watch + // doesn't represent the latest state, this implies some earlier + // event from the watch did, and if we happened to have stopped the + // watch at that point we would have missed some data! + + // Modify the kubernetes policies + found := 0 + for _, kvp := range l.KVPairs { + name := strings.TrimPrefix(kvp.Value.(*apiv3.GlobalNetworkPolicy).Name, "kanp.adminnetworkpolicy.") + p, err := anpClient.AdminNetworkPolicies().Get(ctx, name, metav1.GetOptions{}) + Expect(err).ToNot(HaveOccurred()) + p.SetLabels(map[string]string{"test": "00"}) + _, err = anpClient.AdminNetworkPolicies().Update(ctx, p, metav1.UpdateOptions{}) + Expect(err).ToNot(HaveOccurred()) + found++ + } + Expect(found).To(Equal(2)) + + log.WithField("revision", l.Revision).Info("[TEST] first watch") + watch, err := c.Watch(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, l.Revision) + Expect(err).NotTo(HaveOccurred()) + + event := ExpectModifiedEvent(watch.ResultChan()) + log.WithField("revision", event.New.Revision).Info("[TEST] first k8s event") + event = ExpectModifiedEvent(watch.ResultChan()) + log.WithField("revision", event.New.Revision).Info("[TEST] second k8s event") + + // There should be no more events + Expect(watch.ResultChan()).ToNot(Receive()) + watch.Stop() + + // Make a second change to one of the NPs + for _, kvp := range l.KVPairs { + name := strings.TrimPrefix(kvp.Value.(*apiv3.GlobalNetworkPolicy).Name, "kanp.adminnetworkpolicy.") + p, err := anpClient.AdminNetworkPolicies().Get(ctx, name, metav1.GetOptions{}) + Expect(err).ToNot(HaveOccurred()) + p.SetLabels(map[string]string{"test": "01"}) + _, err = anpClient.AdminNetworkPolicies().Update(ctx, p, metav1.UpdateOptions{}) + Expect(err).ToNot(HaveOccurred()) + break + } + + // Resume watching at the revision of the event we got + log.WithField("revision", event.New.Revision).Info("second watch") + watch, err = c.Watch(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, event.New.Revision) + Expect(err).NotTo(HaveOccurred()) + + // We should only get 1 update, because the event from the previous watch should have been "latest" + ExpectModifiedEvent(watch.ResultChan()) + + // There should be no more events + Expect(watch.ResultChan()).ToNot(Receive()) + watch.Stop() + }) + It("supports watching from part way through a list (calico)", func() { // Only 2 Calico NPs l, err := c.List(ctx, model.ResourceListOptions{Kind: apiv3.KindNetworkPolicy}, "") @@ -2827,7 +3271,7 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore }) It("supports watching from part way through a list (k8s)", func() { - // Only 2 Calico NPs + // Only 2 k8s NPs l, err := c.List(ctx, model.ResourceListOptions{Kind: model.KindKubernetesNetworkPolicy}, "") Expect(err).ToNot(HaveOccurred()) Expect(l.KVPairs).To(HaveLen(2)) @@ -2847,6 +3291,28 @@ var _ = testutils.E2eDatastoreDescribe("Test Watch support", testutils.Datastore watch.Stop() } }) + + It("supports watching from part way through a list of Admin Network Policies", func() { + // Only 2 k8s ANPs + l, err := c.List(ctx, model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, "") + Expect(err).ToNot(HaveOccurred()) + Expect(l.KVPairs).To(HaveLen(2)) + + // Watch from part way + for i := 0; i < 2; i++ { + revision := l.KVPairs[i].Revision + log.WithFields(log.Fields{ + "revision": revision, + "key": l.KVPairs[i].Key.String(), + }).Info("[Test] starting watch") + watch, err := c.Watch(ctx, model.ResourceListOptions{Kind: apiv3.KindGlobalNetworkPolicy}, revision) + Expect(err).ToNot(HaveOccurred()) + // Since the items in the list aren't guaranteed to be in any specific order, we + // can't assert anything useful about what you should get out of this watch, so we + // just confirm that there is no error. + watch.Stop() + } + }) }) Describe("watching Custom Resources", func() { diff --git a/libcalico-go/lib/backend/k8s/resources/customresource.go b/libcalico-go/lib/backend/k8s/resources/customresource.go index 51f6db0083e..5316626cf24 100644 --- a/libcalico-go/lib/backend/k8s/resources/customresource.go +++ b/libcalico-go/lib/backend/k8s/resources/customresource.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,10 @@ package resources import ( "context" + "errors" "fmt" "reflect" + "strings" log "github.com/sirupsen/logrus" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -30,6 +32,8 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/libcalico-go/lib/backend/api" "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" @@ -100,7 +104,7 @@ func (c *customK8sResourceClient) Create(ctx context.Context, kvp *model.KVPair) // Convert the KVPair to the K8s resource. resIn, err := c.convertKVPairToResource(kvp) if err != nil { - logContext.WithError(err).Debug("Error creating resource") + logContext.WithError(err).Debug("Error converting to k8s resource") return nil, err } @@ -193,6 +197,56 @@ func (c *customK8sResourceClient) Update(ctx context.Context, kvp *model.KVPair) return kvp, nil } +// UpdateStatus updates status section of an existing Custom K8s Resource instance in the k8s API from the supplied KVPair. +func (c *customK8sResourceClient) UpdateStatus(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { + logContext := log.WithFields(log.Fields{ + "Key": kvp.Key, + "Value": kvp.Value, + "Parent Resource": c.resource, + }) + logContext.Debug("UpdateStatus custom Kubernetes resource") + + // Create storage for the updated resource. + resOut := reflect.New(c.k8sResourceType).Interface().(Resource) + + var updateError error + // Convert the KVPair to a K8s resource. + resIn, err := c.convertKVPairToResource(kvp) + if err != nil { + logContext.WithError(err).Debug("Error updating resource status") + return nil, err + } + + // Send the update request using the name. + name := resIn.GetObjectMeta().GetName() + namespace := resIn.GetObjectMeta().GetNamespace() + logContext = logContext.WithField("Name", name) + logContext.Debug("Update resource status by name") + updateError = c.restClient.Put(). + Resource(c.resource). + SubResource("status"). + NamespaceIfScoped(namespace, c.namespaced). + Body(resIn). + Name(name). + Do(ctx).Into(resOut) + if updateError != nil { + // Failed to update the resource. + logContext.WithError(updateError).Error("Error updating resource status") + return nil, K8sErrorToCalico(updateError, kvp.Key) + } + + // Update the return data with the metadata populated by the (Kubernetes) datastore. + kvp, err = c.convertResourceToKVPair(resOut) + if err != nil { + logContext.WithError(err).Debug("Error converting returned K8s resource to Calico resource") + return nil, K8sErrorToCalico(err, kvp.Key) + } + // Success. Update the revision information from the response. + kvp.Revision = resOut.GetObjectMeta().GetResourceVersion() + + return kvp, nil +} + func (c *customK8sResourceClient) DeleteKVP(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { return c.Delete(ctx, kvp.Key, kvp.Revision, kvp.UID) } @@ -323,22 +377,46 @@ func (c *customK8sResourceClient) List(ctx context.Context, list model.ListInter // listFunc performs a list with the given options. listFunc := func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { out := reflect.New(c.k8sListType).Interface().(ResourceList) - err := c.restClient.Get(). + + // Build the request. + req := c.restClient.Get(). NamespaceIfScoped(namespace, c.namespaced). Resource(c.resource). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx).Into(out) + VersionedParams(&opts, scheme.ParameterCodec) + + // If the prefix is specified, look for the resources with the label + // of prefix. + if list.(model.ResourceListOptions).Prefix { + // The prefix has a trailing "." character, remove it, since it is not valid for k8s labels + if !strings.HasSuffix(list.(model.ResourceListOptions).Name, ".") { + return nil, errors.New("internal error: custom resource list invoked for a prefix not in the form '.'") + } + name := list.(model.ResourceListOptions).Name[:len(list.(model.ResourceListOptions).Name)-1] + if name == "default" { + req = req.VersionedParams(&metav1.ListOptions{ + LabelSelector: "!" + apiv3.LabelTier, + }, scheme.ParameterCodec) + } else { + req = req.VersionedParams(&metav1.ListOptions{ + LabelSelector: apiv3.LabelTier + "=" + name, + }, scheme.ParameterCodec) + } + } + + // Perform the request. + err := req.Do(ctx).Into(out) if err != nil { // Don't return errors for "not found". This just // means there are no matching Custom K8s Resources, and we should return // an empty list. if !kerrors.IsNotFound(err) { - logContext.WithError(err).Debug("Error listing resources") + log.WithError(err).Debug("Error listing resources") return nil, err } } return out, nil } + convertFunc := func(r Resource) ([]*model.KVPair, error) { kvp, err := c.convertResourceToKVPair(r) if err != nil { @@ -394,7 +472,7 @@ func (c *customK8sResourceClient) listInterfaceToKey(l model.ListInterface) mode key.Namespace = pl.Namespace } - if pl.Name != "" { + if pl.Name != "" && !pl.Prefix { return key } return nil diff --git a/libcalico-go/lib/backend/k8s/resources/ipam_handle.go b/libcalico-go/lib/backend/k8s/resources/ipam_handle.go index 19b58626d67..2624e44fecc 100644 --- a/libcalico-go/lib/backend/k8s/resources/ipam_handle.go +++ b/libcalico-go/lib/backend/k8s/resources/ipam_handle.go @@ -190,7 +190,7 @@ func (c *ipamHandleClient) Get(ctx context.Context, key model.Key, revision stri if _, err := c.DeleteKVP(ctx, v1kvp); err != nil { return nil, err } - return nil, cerrors.ErrorResourceDoesNotExist{fmt.Errorf("Resource was deleted"), key} + return nil, cerrors.ErrorResourceDoesNotExist{Err: fmt.Errorf("%s", "Resource was deleted"), Identifier: key} } return v1kvp, nil diff --git a/libcalico-go/lib/backend/k8s/resources/kubeadminnetworkpolicy.go b/libcalico-go/lib/backend/k8s/resources/kubeadminnetworkpolicy.go new file mode 100644 index 00000000000..8c79a8e013d --- /dev/null +++ b/libcalico-go/lib/backend/k8s/resources/kubeadminnetworkpolicy.go @@ -0,0 +1,139 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resources + +import ( + "context" + "errors" + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/libcalico-go/lib/backend/api" + "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" + cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + adminpolicy "sigs.k8s.io/network-policy-api/apis/v1alpha1" + adminpolicyclient "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned/typed/apis/v1alpha1" +) + +// NewKubernetesAdminNetworkPolicyClient returns a new client for interacting with Kubernetes AdminNetworkPolicy objects. +// Note that this client is only intended for use by the felix syncer in KDD mode, and as such is largely unimplemented +// except for the functions required by the syncer. +func NewKubernetesAdminNetworkPolicyClient( + anpClient *adminpolicyclient.PolicyV1alpha1Client, +) K8sResourceClient { + return &adminNetworkPolicyClient{ + Converter: conversion.NewConverter(), + adminPolicyClient: anpClient, + } +} + +// Implements the api.Client interface for Kubernetes NetworkPolicy. +type adminNetworkPolicyClient struct { + conversion.Converter + adminPolicyClient *adminpolicyclient.PolicyV1alpha1Client +} + +func (c *adminNetworkPolicyClient) Create(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { + log.Debug("Received Create request on AdminNetworkPolicy type") + return nil, cerrors.ErrorOperationNotSupported{ + Identifier: kvp.Key, + Operation: "Create", + } +} + +func (c *adminNetworkPolicyClient) Update(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { + log.Debug("Received Update request on AdminNetworkPolicy type") + return nil, cerrors.ErrorOperationNotSupported{ + Identifier: kvp.Key, + Operation: "Update", + } +} + +func (c *adminNetworkPolicyClient) DeleteKVP(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { + return c.Delete(ctx, kvp.Key, kvp.Revision, kvp.UID) +} + +func (c *adminNetworkPolicyClient) Delete(ctx context.Context, key model.Key, revision string, uid *types.UID) (*model.KVPair, error) { + log.Debug("Received Delete request on AdminNetworkPolicy type") + return nil, cerrors.ErrorOperationNotSupported{ + Identifier: key, + Operation: "Delete", + } +} + +func (c *adminNetworkPolicyClient) Get(ctx context.Context, key model.Key, revision string) (*model.KVPair, error) { + log.Debug("Received Get request on AdminNetworkPolicy type") + return nil, cerrors.ErrorOperationNotSupported{ + Identifier: key, + Operation: "Get", + } +} + +func (c *adminNetworkPolicyClient) List(ctx context.Context, list model.ListInterface, revision string) (*model.KVPairList, error) { + logContext := log.WithField("Resource", "AdminNetworkPolicy") + logContext.Debug("Received List request") + + listFunc := func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { + return c.adminPolicyClient.AdminNetworkPolicies().List(ctx, opts) + } + convertFunc := func(r Resource) ([]*model.KVPair, error) { + anp := r.(*adminpolicy.AdminNetworkPolicy) + kvp, err := c.K8sAdminNetworkPolicyToCalico(anp) + // Silently ignore rule conversion errors. We don't expect any conversion errors + // since the data given to us here is validated by the Kubernetes API. The conversion + // code ignores any rules that it cannot parse, and we will pass the valid ones to Felix. + var e *cerrors.ErrorAdminPolicyConversion + if err != nil && !errors.As(err, &e) { + return nil, err + } + return []*model.KVPair{kvp}, nil + } + return pagedList(ctx, logContext, revision, list, convertFunc, listFunc) +} + +func (c *adminNetworkPolicyClient) Watch(ctx context.Context, list model.ListInterface, revision string) (api.WatchInterface, error) { + // Build watch options to pass to k8s. + opts := metav1.ListOptions{Watch: true, AllowWatchBookmarks: false} + _, ok := list.(model.ResourceListOptions) + if !ok { + return nil, fmt.Errorf("ListInterface is not a ResourceListOptions: %s", list) + } + + opts.ResourceVersion = revision + log.Debugf("Watching Kubernetes AdminNetworkPolicy at revision %q", revision) + k8sRawWatch, err := c.adminPolicyClient.AdminNetworkPolicies().Watch(ctx, opts) + if err != nil { + return nil, K8sErrorToCalico(err, list) + } + converter := func(r Resource) (*model.KVPair, error) { + anp, ok := r.(*adminpolicy.AdminNetworkPolicy) + if !ok { + return nil, errors.New("Kubernetes AdminNetworkPolicy conversion with incorrect k8s resource type") + } + + return c.K8sAdminNetworkPolicyToCalico(anp) + } + return newK8sWatcherConverter(ctx, "Kubernetes AdminNetworkPolicy", converter, k8sRawWatch), nil +} + +func (c *adminNetworkPolicyClient) EnsureInitialized() error { + return nil +} diff --git a/libcalico-go/lib/backend/k8s/resources/resources.go b/libcalico-go/lib/backend/k8s/resources/resources.go index b70a061d433..b2ae40eba97 100644 --- a/libcalico-go/lib/backend/k8s/resources/resources.go +++ b/libcalico-go/lib/backend/k8s/resources/resources.go @@ -308,6 +308,14 @@ func ConvertK8sResourceToCalicoResource(res Resource) error { meta.SetCreationTimestamp(rom.GetCreationTimestamp()) } + // If no creation timestamp was stored in the metadata annotation, use the one from the CR. + // The timestamp is normally set in the clientv3 code. However, for objects that bypass + // the v3 client (e.g., IPAM), we won't have generated a creation timestamp and the field + // is required on update calls. + if meta.GetCreationTimestamp().Time.IsZero() { + meta.SetCreationTimestamp(rom.GetCreationTimestamp()) + } + // Overwrite the K8s metadata with the Calico metadata. meta.DeepCopyInto(rom.(*metav1.ObjectMeta)) diff --git a/libcalico-go/lib/backend/k8s/resources/tiers.go b/libcalico-go/lib/backend/k8s/resources/tiers.go new file mode 100644 index 00000000000..b4363282d00 --- /dev/null +++ b/libcalico-go/lib/backend/k8s/resources/tiers.go @@ -0,0 +1,64 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resources + +import ( + "fmt" + "reflect" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + cresources "github.com/projectcalico/calico/libcalico-go/lib/resources" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +const ( + TierResourceName = "Tiers" + TierCRDName = "tiers.crd.projectcalico.org" +) + +func NewTierClient(c *kubernetes.Clientset, r *rest.RESTClient) K8sResourceClient { + return &customK8sResourceClient{ + clientSet: c, + restClient: r, + name: TierCRDName, + resource: TierResourceName, + description: "Calico Tiers", + k8sResourceType: reflect.TypeOf(apiv3.Tier{}), + k8sResourceTypeMeta: metav1.TypeMeta{ + Kind: apiv3.KindTier, + APIVersion: apiv3.GroupVersionCurrent, + }, + k8sListType: reflect.TypeOf(apiv3.TierList{}), + resourceKind: apiv3.KindTier, + versionconverter: tierv1v3Converter{}, + } +} + +// tierv1v3Converter implements VersionConverter interface. +type tierv1v3Converter struct{} + +// ConvertFromK8s converts v1 Tier Resource to v3 Tier resource +func (c tierv1v3Converter) ConvertFromK8s(inRes Resource) (Resource, error) { + tier, ok := inRes.(*apiv3.Tier) + if !ok { + return nil, fmt.Errorf("invalid type conversion") + } + cresources.DefaultTierFields(tier) + return tier, nil +} diff --git a/libcalico-go/lib/backend/model/block.go b/libcalico-go/lib/backend/model/block.go index e06b46d59f6..aa365f990f0 100644 --- a/libcalico-go/lib/backend/model/block.go +++ b/libcalico-go/lib/backend/model/block.go @@ -216,7 +216,7 @@ func (b *AllocationBlock) NumAddresses() int { // Find the ordinal (i.e. how far into the block) a given IP lies. Returns an error if the IP is outside the block. func (b *AllocationBlock) IPToOrdinal(ip net.IP) (int, error) { ipAsInt := net.IPToBigInt(ip) - baseInt := net.IPToBigInt(net.IP{b.CIDR.IP}) + baseInt := net.IPToBigInt(net.IP{IP: b.CIDR.IP}) ord := big.NewInt(0).Sub(ipAsInt, baseInt).Int64() if ord < 0 || ord >= int64(b.NumAddresses()) { return 0, fmt.Errorf("IP %s not in block %s", ip, b.CIDR) diff --git a/libcalico-go/lib/backend/model/keys.go b/libcalico-go/lib/backend/model/keys.go index 914be3be957..b68c2b62a71 100644 --- a/libcalico-go/lib/backend/model/keys.go +++ b/libcalico-go/lib/backend/model/keys.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -125,12 +125,24 @@ func KeyToDefaultPath(key Key) (string, error) { // directories and leaves) key/value datastore such as etcd v3. // // KeyToDefaultDeletePath returns a different path to KeyToDefaultPath when -// it is a passed a Key that represents a non-leaf which, for example, has its -// own metadata but also contains other resource types as children. +// it is a passed a Key that represents a non-leaf, such as a TierKey. (A +// tier has its own metadata but it also contains policies as children.) // // KeyToDefaultDeletePath returns the common prefix of the non-leaf key and // its children so that a recursive delete of that key would delete the // object itself and any children it has. +// +// For example, KeyToDefaultDeletePath(TierKey{Tier: "a"}) returns +// +// "/calico/v1/policy/tier/a" +// +// which is a prefix of both KeyToDefaultPath(TierKey{Tier: "a"}): +// +// "/calico/v1/policy/tier/a/metadata" +// +// and KeyToDefaultPath(PolicyKey{Tier: "a", Name: "b"}): +// +// "/calico/v1/policy/tier/a/policy/b" func KeyToDefaultDeletePath(key Key) (string, error) { return key.defaultDeletePath() } @@ -167,7 +179,19 @@ func KeyToDefaultDeleteParentPaths(key Key) ([]string, error) { // ListOptionsToDefaultPathRoot converts list options struct into a // common-prefix path suitable for querying a datastore that uses the paths -// returned by KeyToDefaultPath. +// returned by KeyToDefaultPath. For example, +// +// ListOptionsToDefaultPathRoot(TierListOptions{}) +// +// doesn't specify any particular tier so it returns +// "/calico/v1/policy/tier" which is a prefix for all tiers. The datastore +// must then do a recursive query to find all children of that path. +// However, +// +// ListOptionsToDefaultPathRoot(TierListOptions{Tier:"a"}) +// +// returns a more-specific path, which filters down to the specific tier of +// interest: "/calico/v1/policy/tier/a" func ListOptionsToDefaultPathRoot(listOptions ListInterface) string { return listOptions.defaultPathRoot() } @@ -247,7 +271,7 @@ func keyFromDefaultPathInner(path string, parts []string) Key { } case "config": return HostConfigKey{ - Hostname: hostname, + Hostname: unescapeName(hostname), Name: strings.Join(parts[5:], "/"), } case "metadata": @@ -262,14 +286,14 @@ func keyFromDefaultPathInner(path string, parts []string) Key { return nil } return HostIPKey{ - Hostname: hostname, + Hostname: unescapeName(hostname), } case "wireguard": if len(parts) != 5 { return nil } return WireguardKey{ - NodeName: hostname, + NodeName: unescapeName(hostname), } } case "netset": @@ -294,11 +318,19 @@ func keyFromDefaultPathInner(path string, parts []string) Key { return nil } switch parts[5] { + case "metadata": + if len(parts) != 6 { + return nil + } + return TierKey{ + Name: unescapeName(parts[4]), + } case "policy": if len(parts) != 7 { return nil } return PolicyKey{ + Tier: unescapeName(parts[4]), Name: unescapeName(parts[6]), } } @@ -484,6 +516,7 @@ func OldKeyFromDefaultPath(path string) Key { } else if m := matchPolicy.FindStringSubmatch(path); m != nil { log.Debugf("Path is a policy: %v", path) return PolicyKey{ + Tier: unescapeName(m[1]), Name: unescapeName(m[2]), } } else if m := matchProfile.FindStringSubmatch(path); m != nil { @@ -498,12 +531,15 @@ func OldKeyFromDefaultPath(path string) Key { return ProfileLabelsKey{ProfileKey: pk} } return nil + } else if m := matchTier.FindStringSubmatch(path); m != nil { + log.Debugf("Path is a policy tier: %v", path) + return TierKey{Name: m[1]} } else if m := matchHostIp.FindStringSubmatch(path); m != nil { log.Debugf("Path is a host ID: %v", path) - return HostIPKey{Hostname: m[1]} + return HostIPKey{Hostname: unescapeName(m[1])} } else if m := matchWireguard.FindStringSubmatch(path); m != nil { log.Debugf("Path is a node name: %v", path) - return WireguardKey{NodeName: m[1]} + return WireguardKey{NodeName: unescapeName(m[1])} } else if m := matchIPPool.FindStringSubmatch(path); m != nil { log.Debugf("Path is a pool: %v", path) mungedCIDR := m[1] @@ -519,7 +555,7 @@ func OldKeyFromDefaultPath(path string) Key { return GlobalConfigKey{Name: m[1]} } else if m := matchHostConfig.FindStringSubmatch(path); m != nil { log.Debugf("Path is a host config: %v", path) - return HostConfigKey{Hostname: m[1], Name: m[2]} + return HostConfigKey{Hostname: unescapeName(m[1]), Name: m[2]} } else if matchReadyFlag.MatchString(path) { log.Debugf("Path is a ready flag: %v", path) return ReadyFlagKey{} diff --git a/libcalico-go/lib/backend/model/keys_test.go b/libcalico-go/lib/backend/model/keys_test.go index f72258329e1..b88230c7601 100644 --- a/libcalico-go/lib/backend/model/keys_test.go +++ b/libcalico-go/lib/backend/model/keys_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ var interestingPaths = []string{ "/calico/v1/policy/tier/foo", "/calico/v1/policy/tier/foo/policy", "/calico/v1/policy/tier/foo/policy/bar", + "/calico/v1/policy/tier/foo/metadata", "/calico/v1/policy/profile", "/calico/bgp/v1/global", "/calico/bgp/v1/global/peer_v4", @@ -290,7 +291,7 @@ var _ = DescribeTable( Entry( "policy with a /", "/calico/v1/policy/tier/default/policy/biff%2fbop", - PolicyKey{Name: "biff/bop"}, + PolicyKey{Tier: "default", Name: "biff/bop"}, false, ), Entry( diff --git a/libcalico-go/lib/backend/model/kubeadminnetworkpolicy.go b/libcalico-go/lib/backend/model/kubeadminnetworkpolicy.go new file mode 100644 index 00000000000..899b3511d65 --- /dev/null +++ b/libcalico-go/lib/backend/model/kubeadminnetworkpolicy.go @@ -0,0 +1,19 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +const ( + KindKubernetesAdminNetworkPolicy = "KubernetesAdminNetworkPolicy" +) diff --git a/libcalico-go/lib/backend/model/policy.go b/libcalico-go/lib/backend/model/policy.go index 72cb5d7c5b8..ca7955587e9 100644 --- a/libcalico-go/lib/backend/model/policy.go +++ b/libcalico-go/lib/backend/model/policy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,14 +33,18 @@ var ( type PolicyKey struct { Name string `json:"-" validate:"required,name"` + Tier string `json:"-" validate:"required,name"` } func (key PolicyKey) defaultPath() (string, error) { + if key.Tier == "" { + return "", errors.ErrorInsufficientIdentifiers{Name: "tier"} + } if key.Name == "" { return "", errors.ErrorInsufficientIdentifiers{Name: "name"} } - e := fmt.Sprintf("/calico/v1/policy/tier/default/policy/%s", - escapeName(key.Name)) + e := fmt.Sprintf("/calico/v1/policy/tier/%s/policy/%s", + key.Tier, escapeName(key.Name)) return e, nil } @@ -57,15 +61,20 @@ func (key PolicyKey) valueType() (reflect.Type, error) { } func (key PolicyKey) String() string { - return fmt.Sprintf("Policy(name=%s)", key.Name) + return fmt.Sprintf("Policy(tier=%s, name=%s)", key.Tier, key.Name) } type PolicyListOptions struct { Name string + Tier string } func (options PolicyListOptions) defaultPathRoot() string { - k := "/calico/v1/policy/tier/default/policy" + k := "/calico/v1/policy/tier" + if options.Tier == "" { + return k + } + k = k + fmt.Sprintf("/%s/policy", options.Tier) if options.Name == "" { return k } @@ -80,12 +89,17 @@ func (options PolicyListOptions) KeyFromDefaultPath(path string) Key { log.Debugf("Didn't match regex") return nil } + tier := r[0][1] name := unescapeName(r[0][2]) + if options.Tier != "" && tier != options.Tier { + log.Infof("Didn't match tier %s != %s", options.Tier, tier) + return nil + } if options.Name != "" && name != options.Name { log.Debugf("Didn't match name %s != %s", options.Name, name) return nil } - return PolicyKey{Name: name} + return PolicyKey{Tier: tier, Name: name} } type Policy struct { diff --git a/libcalico-go/lib/backend/model/resource.go b/libcalico-go/lib/backend/model/resource.go index b0a5ea844dd..f7bdeaac985 100644 --- a/libcalico-go/lib/backend/model/resource.go +++ b/libcalico-go/lib/backend/model/resource.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -95,6 +95,11 @@ func init() { "globalnetworksets", reflect.TypeOf(apiv3.GlobalNetworkSet{}), ) + registerResourceInfo( + KindKubernetesAdminNetworkPolicy, + "kubernetesadminnetworkpolicies", + reflect.TypeOf(apiv3.GlobalNetworkPolicy{}), + ) registerResourceInfo( apiv3.KindIPPool, "ippools", @@ -125,6 +130,11 @@ func init() { "networksets", reflect.TypeOf(apiv3.NetworkSet{}), ) + registerResourceInfo( + apiv3.KindTier, + "tiers", + reflect.TypeOf(apiv3.Tier{}), + ) registerResourceInfo( libapiv3.KindNode, "nodes", @@ -202,7 +212,7 @@ func (key ResourceKey) defaultDeleteParentPaths() ([]string, error) { func (key ResourceKey) valueType() (reflect.Type, error) { ri, ok := resourceInfoByKindLower[strings.ToLower(key.Kind)] if !ok { - return nil, fmt.Errorf("Unexpected resource kind: " + key.Kind) + return nil, fmt.Errorf("unexpected resource kind: %s", key.Kind) } return ri.typeOf, nil } diff --git a/libcalico-go/lib/backend/model/tier.go b/libcalico-go/lib/backend/model/tier.go new file mode 100644 index 00000000000..fd7a2a617e6 --- /dev/null +++ b/libcalico-go/lib/backend/model/tier.go @@ -0,0 +1,95 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "fmt" + "regexp" + + "reflect" + + log "github.com/sirupsen/logrus" + + v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/libcalico-go/lib/errors" +) + +var ( + matchTier = regexp.MustCompile("^/?calico/v1/policy/tier/([^/]+)/metadata$") + typeTier = reflect.TypeOf(Tier{}) +) + +type TierKey struct { + Name string `json:"-" validate:"required,name"` +} + +func (key TierKey) defaultPath() (string, error) { + k, err := key.defaultDeletePath() + return k + "/metadata", err +} + +func (key TierKey) defaultDeletePath() (string, error) { + if key.Name == "" { + return "", errors.ErrorInsufficientIdentifiers{Name: "name"} + } + e := fmt.Sprintf("/calico/v1/policy/tier/%s", key.Name) + return e, nil +} + +func (key TierKey) defaultDeleteParentPaths() ([]string, error) { + return nil, nil +} + +func (key TierKey) valueType() (reflect.Type, error) { + return typeTier, nil +} + +func (key TierKey) String() string { + return fmt.Sprintf("Tier(name=%s)", key.Name) +} + +type TierListOptions struct { + Name string +} + +func (options TierListOptions) defaultPathRoot() string { + k := "/calico/v1/policy/tier" + if options.Name == "" { + return k + } + k = k + fmt.Sprintf("/%s/metadata", options.Name) + return k +} + +func (options TierListOptions) KeyFromDefaultPath(path string) Key { + log.Infof("Get Tier key from %s", path) + r := matchTier.FindAllStringSubmatch(path, -1) + if len(r) != 1 { + log.Infof("Didn't match regex") + return nil + } + name := r[0][1] + if options.Name != "" && name != options.Name { + log.Infof("Didn't match name %s != %s", options.Name, name) + return nil + } + return TierKey{Name: name} +} + +type Tier struct { + Order *float64 `json:"order,omitempty"` + DefaultAction v3.Action `json:"defaultAction,omitempty"` +} diff --git a/libcalico-go/lib/backend/syncersv1/bgpsyncer/bgpsyncer_e2e_test.go b/libcalico-go/lib/backend/syncersv1/bgpsyncer/bgpsyncer_e2e_test.go index 23064eb56b5..de4ea62211a 100644 --- a/libcalico-go/lib/backend/syncersv1/bgpsyncer/bgpsyncer_e2e_test.go +++ b/libcalico-go/lib/backend/syncersv1/bgpsyncer/bgpsyncer_e2e_test.go @@ -156,7 +156,7 @@ var _ = testutils.E2eDatastoreDescribe("BGP syncer tests", testutils.DatastoreAl Expect(err).NotTo(HaveOccurred()) syncTester.ExpectCacheSize(expectedCacheSize) - syncTester.ExpectNoData(model.GlobalBGPConfigKey{"as_num"}) + syncTester.ExpectNoData(model.GlobalBGPConfigKey{Name: "as_num"}) By("Creating an IPPool") poolCIDR := "192.124.0.0/21" diff --git a/libcalico-go/lib/backend/syncersv1/dedupebuffer/dedupe_buffer_test.go b/libcalico-go/lib/backend/syncersv1/dedupebuffer/dedupe_buffer_test.go index 5eddcd575e1..9e5bcb84ce3 100644 --- a/libcalico-go/lib/backend/syncersv1/dedupebuffer/dedupe_buffer_test.go +++ b/libcalico-go/lib/backend/syncersv1/dedupebuffer/dedupe_buffer_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2023-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,8 +28,8 @@ import ( ) func init() { - logrus.AddHook(&logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) + // Set up logging formatting. + logutils.ConfigureFormatter("test") logrus.SetLevel(logrus.DebugLevel) } diff --git a/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncer_e2e_test.go b/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncer_e2e_test.go index bebddaa3cd2..317880d77a7 100644 --- a/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncer_e2e_test.go +++ b/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncer_e2e_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,6 +38,7 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/backend/syncersv1/felixsyncer" "github.com/projectcalico/calico/libcalico-go/lib/clientv3" "github.com/projectcalico/calico/libcalico-go/lib/ipam" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/net" "github.com/projectcalico/calico/libcalico-go/lib/options" "github.com/projectcalico/calico/libcalico-go/lib/resources" @@ -51,6 +52,7 @@ const ( // calculateDefaultFelixSyncerEntries determines the expected set of Felix configuration for the currently configured // cluster. func calculateDefaultFelixSyncerEntries(cs kubernetes.Interface, dt apiconfig.DatastoreType) (expected []model.KVPair) { + defaultProfileRules := []model.Rule{{Action: "allow"}} // Add 2 for the default-allow profile that is always there. // However, no profile labels are in the list because the // default-allow profile doesn't specify labels. @@ -59,8 +61,8 @@ func calculateDefaultFelixSyncerEntries(cs kubernetes.Interface, dt apiconfig.Da expected = append(expected, model.KVPair{ Key: model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: "projectcalico-default-allow"}}, Value: &model.ProfileRules{ - InboundRules: []model.Rule{{Action: "allow"}}, - OutboundRules: []model.Rule{{Action: "allow"}}, + InboundRules: defaultProfileRules, + OutboundRules: defaultProfileRules, }, }) @@ -124,8 +126,8 @@ func calculateDefaultFelixSyncerEntries(cs kubernetes.Interface, dt apiconfig.Da expected = append(expected, model.KVPair{ Key: model.ProfileRulesKey{ProfileKey: model.ProfileKey{Name: name}}, Value: &model.ProfileRules{ - InboundRules: []model.Rule{{Action: "allow"}}, - OutboundRules: []model.Rule{{Action: "allow"}}, + InboundRules: defaultProfileRules, + OutboundRules: defaultProfileRules, }, }) @@ -395,6 +397,9 @@ var _ = testutils.E2eDatastoreDescribe("Felix syncer tests", testutils.Datastore ) Expect(err).NotTo(HaveOccurred()) + // Add 1 for the Node resource passed over the felix syncer. + expectedCacheSize += 1 + // Creating the node initialises the ClusterInformation as a side effect. syncTester.ExpectData(model.KVPair{ Key: model.ReadyFlagKey{}, @@ -404,13 +409,20 @@ var _ = testutils.E2eDatastoreDescribe("Felix syncer tests", testutils.Datastore model.GlobalConfigKey{Name: "ClusterGUID"}, MatchRegexp("[a-f0-9]{32}"), ) + // Creating the node also creates default and adminnetworkpolicy tiers. + order := apiv3.DefaultTierOrder syncTester.ExpectData(model.KVPair{ - Key: model.HostConfigKey{Hostname: "127.0.0.1", Name: "IpInIpTunnelAddr"}, - Value: "192.168.0.1", + Key: model.TierKey{Name: "default"}, + Value: &model.Tier{Order: &order, DefaultAction: apiv3.Deny}, }) + anpOrder := apiv3.AdminNetworkPolicyTierOrder syncTester.ExpectData(model.KVPair{ - Key: model.HostConfigKey{Hostname: "127.0.0.1", Name: "VXLANTunnelMACAddr"}, - Value: "66:cf:23:df:22:07", + Key: model.TierKey{Name: names.AdminNetworkPolicyTierName}, + Value: &model.Tier{Order: &anpOrder, DefaultAction: apiv3.Pass}, + }) + syncTester.ExpectData(model.KVPair{ + Key: model.HostConfigKey{Hostname: "127.0.0.1", Name: "IpInIpTunnelAddr"}, + Value: "192.168.0.1", }) syncTester.ExpectData(model.KVPair{ Key: model.HostConfigKey{Hostname: "127.0.0.1", Name: "VXLANTunnelMACAddr"}, @@ -421,7 +433,7 @@ var _ = testutils.E2eDatastoreDescribe("Felix syncer tests", testutils.Datastore Value: &model.Wireguard{InterfaceIPv4Addr: &wip, PublicKey: "jlkVyQYooZYzI2wFfNhSZez5eWh44yfq1wKVjLvSXgY="}, }) // add one for the node resource - expectedCacheSize += 6 + expectedCacheSize += 7 } // The HostIP will be added for the IPv4 address @@ -621,6 +633,33 @@ var _ = testutils.E2eDatastoreDescribe("Felix syncer tests", testutils.Datastore }, }) + By("Creating a Tier") + tierName := "mytier" + order := float64(100.00) + actionPass := apiv3.Pass + tier, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: tierName}, + Spec: apiv3.TierSpec{ + Order: &order, + DefaultAction: &actionPass, + }, + }, + options.SetOptions{}, + ) + Expect(err).NotTo(HaveOccurred()) + expectedCacheSize += 1 + syncTester.ExpectData(model.KVPair{ + Key: model.TierKey{Name: tierName}, + Value: &model.Tier{ + Order: &order, + DefaultAction: apiv3.Pass, + }, + Revision: tier.ResourceVersion, + }) + syncTester.ExpectCacheSize(expectedCacheSize) + By("Starting a new syncer and verifying that all current entries are returned before sync status") // We need to create a new syncTester and syncer. current := syncTester.GetCacheEntries() diff --git a/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncerv1.go b/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncerv1.go index 0c82e29ea93..19f7595f909 100644 --- a/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncerv1.go +++ b/libcalico-go/lib/backend/syncersv1/felixsyncer/felixsyncerv1.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -74,6 +74,10 @@ func New(client api.Client, cfg apiconfig.CalicoAPIConfigSpec, callbacks api.Syn ListInterface: model.ResourceListOptions{Kind: apiv3.KindNetworkSet}, UpdateProcessor: updateprocessors.NewNetworkSetUpdateProcessor(), }, + { + ListInterface: model.ResourceListOptions{Kind: apiv3.KindTier}, + UpdateProcessor: updateprocessors.NewTierUpdateProcessor(), + }, { ListInterface: model.ResourceListOptions{Kind: apiv3.KindHostEndpoint}, UpdateProcessor: updateprocessors.NewHostEndpointUpdateProcessor(), @@ -90,6 +94,10 @@ func New(client api.Client, cfg apiconfig.CalicoAPIConfigSpec, callbacks api.Syn ListInterface: model.ResourceListOptions{Kind: model.KindKubernetesNetworkPolicy}, UpdateProcessor: updateprocessors.NewNetworkPolicyUpdateProcessor(), }) + additionalTypes = append(additionalTypes, watchersyncer.ResourceType{ + ListInterface: model.ResourceListOptions{Kind: model.KindKubernetesAdminNetworkPolicy}, + UpdateProcessor: updateprocessors.NewGlobalNetworkPolicyUpdateProcessor(), + }) additionalTypes = append(additionalTypes, watchersyncer.ResourceType{ ListInterface: model.ResourceListOptions{Kind: model.KindKubernetesEndpointSlice}, }) diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/bgpnodeprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/bgpnodeprocessor_test.go index 671564244b3..f834ba905f1 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/bgpnodeprocessor_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/bgpnodeprocessor_test.go @@ -356,5 +356,5 @@ func assertBlockAffinityUpdate(kvps []*model.KVPair, expected *model.KVPair) { } e += "]" - Expect(fmt.Errorf(e)).NotTo(HaveOccurred()) + Expect(fmt.Errorf("%s", e)).NotTo(HaveOccurred()) } diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go index 8649ff4f519..fba3de057f2 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go @@ -45,7 +45,7 @@ const ( ) const ( - numBaseFelixConfigs = 140 + numBaseFelixConfigs = 146 ) var _ = Describe("Test the generic configuration update processor and the concrete implementations", func() { @@ -219,6 +219,11 @@ var _ = Describe("Test the generic configuration update processor and the concre res.Spec.ExternalNodesCIDRList = &[]string{"1.1.1.1", "2.2.2.2"} res.Spec.IptablesNATOutgoingInterfaceFilter = "cali-123" res.Spec.RouteTableRanges = &apiv3.RouteTableRanges{{Min: 43, Max: 211}} + res.Spec.NftablesMarkMask = &uint1 + res.Spec.NftablesRefreshInterval = &duration4 + res.Spec.NftablesFilterDenyAction = "Accept" + res.Spec.NftablesFilterAllowAction = "Drop" + res.Spec.NftablesMangleAllowAction = "Accept" expected := map[string]interface{}{ "RouteRefreshInterval": "12.345", "IptablesLockProbeIntervalMillis": "54.321", @@ -232,6 +237,11 @@ var _ = Describe("Test the generic configuration update processor and the concre "ExternalNodesCIDRList": "1.1.1.1,2.2.2.2", "IptablesNATOutgoingInterfaceFilter": "cali-123", "RouteTableRanges": "43-211", + "NftablesRefreshInterval": "0.1", + "NftablesMarkMask": "1313", + "NftablesFilterDenyAction": "Accept", + "NftablesFilterAllowAction": "Drop", + "NftablesMangleAllowAction": "Accept", } kvps, err := cc.Process(&model.KVPair{ Key: perNodeFelixKey, diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/felixnodeprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/felixnodeprocessor_test.go index 314a81a026a..11a31999843 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/felixnodeprocessor_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/felixnodeprocessor_test.go @@ -611,5 +611,5 @@ func assertBlockUpdate(kvps []*model.KVPair, expected *model.KVPair) { } e += "]" - Expect(fmt.Errorf(e)).NotTo(HaveOccurred()) + Expect(fmt.Errorf("%s", e)).NotTo(HaveOccurred()) } diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor.go index ae8d38a0c02..4f36d28fee0 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,25 +23,31 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" "github.com/projectcalico/calico/libcalico-go/lib/backend/watchersyncer" + "github.com/projectcalico/calico/libcalico-go/lib/names" ) // Create a new SyncerUpdateProcessor to sync GlobalNetworkPolicy data in v1 format for // consumption by Felix. func NewGlobalNetworkPolicyUpdateProcessor() watchersyncer.SyncerUpdateProcessor { - return NewSimpleUpdateProcessor(apiv3.KindGlobalNetworkPolicy, convertGlobalNetworkPolicyV2ToV1Key, convertGlobalNetworkPolicyV2ToV1Value) + return NewSimpleUpdateProcessor(apiv3.KindGlobalNetworkPolicy, convertGlobalNetworkPolicyV3ToV1Key, convertGlobalNetworkPolicyV3ToV1Value) } -func convertGlobalNetworkPolicyV2ToV1Key(v3key model.ResourceKey) (model.Key, error) { +func convertGlobalNetworkPolicyV3ToV1Key(v3key model.ResourceKey) (model.Key, error) { if v3key.Name == "" { return model.PolicyKey{}, errors.New("Missing Name field to create a v1 NetworkPolicy Key") } + tier, err := names.TierFromPolicyName(v3key.Name) + if err != nil { + return model.PolicyKey{}, err + } return model.PolicyKey{ Name: v3key.Name, + Tier: tier, }, nil } -func convertGlobalNetworkPolicyV2ToV1Value(val interface{}) (interface{}, error) { +func convertGlobalNetworkPolicyV3ToV1Value(val interface{}) (interface{}, error) { v3res, ok := val.(*apiv3.GlobalNetworkPolicy) if !ok { return nil, errors.New("Value is not a valid GlobalNetworkPolicy resource value") @@ -65,10 +71,10 @@ func convertGlobalNetworkPolicyV2ToV1Value(val interface{}) (interface{}, error) v1value := &model.Policy{ Namespace: "", // Empty string used to signal a GlobalNetworkPolicy. Order: spec.Order, - InboundRules: RulesAPIV2ToBackend(spec.Ingress, ""), - OutboundRules: RulesAPIV2ToBackend(spec.Egress, ""), + InboundRules: RulesAPIV3ToBackend(spec.Ingress, ""), + OutboundRules: RulesAPIV3ToBackend(spec.Egress, ""), Selector: selector, - Types: policyTypesAPIV2ToBackend(spec.Types), + Types: policyTypesAPIV3ToBackend(spec.Types), DoNotTrack: spec.DoNotTrack, PreDNAT: spec.PreDNAT, ApplyOnForward: spec.ApplyOnForward, diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor_test.go index 503f3bcff1d..66c566685a4 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/globalnetworkpolicyprocessor_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,10 +16,17 @@ package updateprocessors_test import ( . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + adminpolicy "sigs.k8s.io/network-policy-api/apis/v1alpha1" + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/api/pkg/lib/numorstring" + "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" "github.com/projectcalico/calico/libcalico-go/lib/backend/syncersv1/updateprocessors" cnet "github.com/projectcalico/calico/libcalico-go/lib/net" @@ -95,7 +102,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { Expect(err).NotTo(HaveOccurred()) Expect(kvps).To(HaveLen(1)) - v1Key := model.PolicyKey{Name: "minimal"} + v1Key := model.PolicyKey{Tier: "default", Name: "minimal"} Expect(kvps[0]).To(Equal(&model.KVPair{ Key: v1Key, Value: &model.Policy{ @@ -112,7 +119,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `mylabel == 'selectme'` - v1Key := model.PolicyKey{Name: "full"} + v1Key := model.PolicyKey{Tier: "default", Name: "full"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) By("should be able to delete the full network policy") @@ -134,7 +141,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { kvps, err := up.Process(&model.KVPair{Key: emptyGNPKey, Value: apiv3.NewHostEndpoint(), Revision: testRev}) Expect(err).NotTo(HaveOccurred()) - v1Key := model.PolicyKey{Name: "empty"} + v1Key := model.PolicyKey{Tier: "default", Name: "empty"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: nil}})) }) @@ -145,7 +152,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `(mylabel == 'selectme') && pcsa.role == "development"` - v1Key := model.PolicyKey{Name: "valid-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "valid-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -155,7 +162,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `mylabel == 'selectme'` - v1Key := model.PolicyKey{Name: "invalid-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "invalid-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -165,7 +172,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `(mylabel == 'selectme') && has(projectcalico.org/serviceaccount)` - v1Key := model.PolicyKey{Name: "all-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "all-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -176,7 +183,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `(mylabel == 'selectme') && pcns.name == "testing"` - v1Key := model.PolicyKey{Name: "valid-ns-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "valid-ns-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -186,7 +193,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `mylabel == 'selectme'` - v1Key := model.PolicyKey{Name: "invalid-ns-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "invalid-ns-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -196,7 +203,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `(mylabel == 'selectme') && has(projectcalico.org/namespace)` - v1Key := model.PolicyKey{Name: "all-ns-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "all-ns-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -207,7 +214,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `((mylabel == 'selectme') && pcns.name == "testing") && pcsa.role == "development"` - v1Key := model.PolicyKey{Name: "sa-and-ns-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "sa-and-ns-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -219,7 +226,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `pcsa.role == "development"` - v1Key := model.PolicyKey{Name: "no-sel-with-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "no-sel-with-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -230,7 +237,7 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `pcns.name == "testing"` - v1Key := model.PolicyKey{Name: "no-sel-with-ns-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "no-sel-with-ns-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -242,8 +249,142 @@ var _ = Describe("Test the GlobalNetworkPolicy update processor", func() { policy := fullGNPv1() policy.Selector = `(pcns.name == "testing") && pcsa.role == "development"` - v1Key := model.PolicyKey{Name: "no-sel-with-ns-and-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: "no-sel-with-ns-and-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) }) }) + +// Define AdminNetworkPolicies and the corresponding expected v1 KVPairs. +// +// anp1 is an AdminNetworkPolicy with a single Egress rule, which contains ports only, +// and no selectors. +var ( + anpOrder = float64(1000.0) + ports = []adminpolicy.AdminNetworkPolicyPort{{ + PortNumber: &adminpolicy.Port{ + Port: 80, + }, + }} + anp1 = adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Subject: adminpolicy.AdminNetworkPolicySubject{ + Namespaces: &metav1.LabelSelector{}, + }, + Priority: 1000, + Egress: []adminpolicy.AdminNetworkPolicyEgressRule{ + { + Action: "Allow", + To: []adminpolicy.AdminNetworkPolicyEgressPeer{ + { + Namespaces: &metav1.LabelSelector{}, + }, + }, + Ports: &ports, + }, + }, + }, + } +) + +// expected1 is the expected v1 KVPair representation of np1 from above. +var ( + expectedModel1 = []*model.KVPair{ + { + Key: model.PolicyKey{Tier: "adminnetworkpolicy", Name: "kanp.adminnetworkpolicy.test.policy"}, + Value: &model.Policy{ + Order: &anpOrder, + Selector: "(projectcalico.org/orchestrator == 'k8s') && has(projectcalico.org/namespace)", + Types: []string{"egress"}, + ApplyOnForward: false, + OutboundRules: []model.Rule{ + { + Action: "allow", + Protocol: &tcp, + SrcSelector: "", + DstSelector: "has(projectcalico.org/namespace)", + OriginalDstNamespaceSelector: "all()", + DstPorts: []numorstring.Port{port80}, + }, + }, + }, + }, + } +) + +// np2 is a NetworkPolicy with a single Ingress rule which allows from all namespaces. +var anp2 = adminpolicy.AdminNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test.policy", + UID: types.UID("30316465-6365-4463-ad63-3564622d3638"), + }, + Spec: adminpolicy.AdminNetworkPolicySpec{ + Subject: adminpolicy.AdminNetworkPolicySubject{ + Pods: &adminpolicy.NamespacedPod{ + PodSelector: metav1.LabelSelector{}, + }, + }, + Priority: 1000, + Ingress: []adminpolicy.AdminNetworkPolicyIngressRule{ + { + Action: "Allow", + From: []adminpolicy.AdminNetworkPolicyIngressPeer{ + { + Namespaces: &metav1.LabelSelector{}, + }, + }, + }, + }, + }, +} + +var expectedModel2 = []*model.KVPair{ + { + Key: model.PolicyKey{ + Name: "kanp.adminnetworkpolicy.test.policy", + Tier: "adminnetworkpolicy", + }, + Value: &model.Policy{ + Order: &anpOrder, + Selector: "(projectcalico.org/orchestrator == 'k8s') && has(projectcalico.org/namespace)", + Types: []string{"ingress"}, + ApplyOnForward: false, + InboundRules: []model.Rule{ + { + Action: "allow", + SrcSelector: "has(projectcalico.org/namespace)", + DstSelector: "", + OriginalSrcSelector: "", + OriginalSrcNamespaceSelector: "all()", + }, + }, + }, + }, +} + +var _ = Describe("Test the AdminNetworkPolicy update processor + conversion", func() { + up := updateprocessors.NewGlobalNetworkPolicyUpdateProcessor() + + DescribeTable("GlobalNetworkPolicy update processor + conversion tests", + func(anp adminpolicy.AdminNetworkPolicy, expected []*model.KVPair) { + // First, convert the NetworkPolicy using the k8s conversion logic. + c := conversion.NewConverter() + kvp, err := c.K8sAdminNetworkPolicyToCalico(&anp) + Expect(err).NotTo(HaveOccurred()) + + // Next, run the policy through the update processor. + out, err := up.Process(kvp) + Expect(err).NotTo(HaveOccurred()) + + // Finally, assert the expected result. + Expect(out).To(Equal(expected)) + }, + + Entry("should handle an AdminNetworkPolicy with no rule selectors", anp1, expectedModel1), + Entry("should handle an AdminNetworkPolicy with an empty ns selector", anp2, expectedModel2), + ) +}) diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor.go index d44e0e9bdfc..513c98f6a7a 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor.go @@ -24,24 +24,30 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/backend/k8s/conversion" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" "github.com/projectcalico/calico/libcalico-go/lib/backend/watchersyncer" + "github.com/projectcalico/calico/libcalico-go/lib/names" ) // Create a new SyncerUpdateProcessor to sync NetworkPolicy data in v1 format for // consumption by Felix. func NewNetworkPolicyUpdateProcessor() watchersyncer.SyncerUpdateProcessor { - return NewSimpleUpdateProcessor(apiv3.KindNetworkPolicy, convertNetworkPolicyV2ToV1Key, convertNetworkPolicyV2ToV1Value) + return NewSimpleUpdateProcessor(apiv3.KindNetworkPolicy, convertNetworkPolicyV3ToV1Key, convertNetworkPolicyV3ToV1Value) } -func convertNetworkPolicyV2ToV1Key(v3key model.ResourceKey) (model.Key, error) { +func convertNetworkPolicyV3ToV1Key(v3key model.ResourceKey) (model.Key, error) { if v3key.Name == "" || v3key.Namespace == "" { return model.PolicyKey{}, errors.New("Missing Name or Namespace field to create a v1 NetworkPolicy Key") } + tier, err := names.TierFromPolicyName(v3key.Name) + if err != nil { + return model.PolicyKey{}, err + } return model.PolicyKey{ Name: v3key.Namespace + "/" + v3key.Name, + Tier: tier, }, nil } -func convertNetworkPolicyV2ToV1Value(val interface{}) (interface{}, error) { +func convertNetworkPolicyV3ToV1Value(val interface{}) (interface{}, error) { v3res, ok := val.(*apiv3.NetworkPolicy) if !ok { return nil, errors.New("Value is not a valid NetworkPolicy resource value") @@ -64,10 +70,10 @@ func convertNetworkPolicyV2ToV1Value(val interface{}) (interface{}, error) { v1value := &model.Policy{ Namespace: v3res.Namespace, Order: spec.Order, - InboundRules: RulesAPIV2ToBackend(spec.Ingress, v3res.Namespace), - OutboundRules: RulesAPIV2ToBackend(spec.Egress, v3res.Namespace), + InboundRules: RulesAPIV3ToBackend(spec.Ingress, v3res.Namespace), + OutboundRules: RulesAPIV3ToBackend(spec.Egress, v3res.Namespace), Selector: selector, - Types: policyTypesAPIV2ToBackend(spec.Types), + Types: policyTypesAPIV3ToBackend(spec.Types), ApplyOnForward: false, PerformanceHints: v3res.Spec.PerformanceHints, } @@ -75,16 +81,16 @@ func convertNetworkPolicyV2ToV1Value(val interface{}) (interface{}, error) { return v1value, nil } -// policyTypesAPIV2ToBackend converts the policy type field value from the API +// policyTypesAPIV3ToBackend converts the policy type field value from the API // value to the equivalent backend value. -func policyTypesAPIV2ToBackend(ptypes []apiv3.PolicyType) []string { +func policyTypesAPIV3ToBackend(ptypes []apiv3.PolicyType) []string { var v1ptypes []string for _, ptype := range ptypes { - v1ptypes = append(v1ptypes, policyTypeAPIV2ToBackend(ptype)) + v1ptypes = append(v1ptypes, policyTypeAPIV3ToBackend(ptype)) } return v1ptypes } -func policyTypeAPIV2ToBackend(ptype apiv3.PolicyType) string { +func policyTypeAPIV3ToBackend(ptype apiv3.PolicyType) string { return strings.ToLower(string(ptype)) } diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor_test.go index c12b19816d8..5ecbaad8c1a 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/networkpolicyprocessor_test.go @@ -75,7 +75,7 @@ var _ = Describe("Test the NetworkPolicy update processor", func() { Expect(err).NotTo(HaveOccurred()) Expect(kvps).To(HaveLen(1)) - v1Key := model.PolicyKey{Name: ns1 + "/minimal"} + v1Key := model.PolicyKey{Tier: "default", Name: ns1 + "/minimal"} Expect(kvps[0]).To(Equal(&model.KVPair{ Key: v1Key, Value: &model.Policy{ @@ -94,7 +94,7 @@ var _ = Describe("Test the NetworkPolicy update processor", func() { policy := fullNPv1(ns2) policy.Selector = fmt.Sprintf("(mylabel == 'selectme') && projectcalico.org/namespace == '%s'", ns2) - v1Key := model.PolicyKey{Name: ns2 + "/full"} + v1Key := model.PolicyKey{Tier: "default", Name: ns2 + "/full"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) By("should be able to delete the full network policy") @@ -116,7 +116,7 @@ var _ = Describe("Test the NetworkPolicy update processor", func() { kvps, err := up.Process(&model.KVPair{Key: emptyNPKey, Value: apiv3.NewHostEndpoint(), Revision: testRev}) Expect(err).NotTo(HaveOccurred()) - v1Key := model.PolicyKey{Name: ns1 + "/empty"} + v1Key := model.PolicyKey{Tier: "default", Name: ns1 + "/empty"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: nil}})) }) @@ -126,7 +126,7 @@ var _ = Describe("Test the NetworkPolicy update processor", func() { policy := fullNPv1(ns2) policy.Selector = `((mylabel == 'selectme') && projectcalico.org/namespace == 'namespace2') && pcsa.role == "development"` - v1Key := model.PolicyKey{Name: ns2 + "/valid-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: ns2 + "/valid-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -136,7 +136,7 @@ var _ = Describe("Test the NetworkPolicy update processor", func() { policy := fullNPv1(ns2) policy.Selector = `(mylabel == 'selectme') && projectcalico.org/namespace == 'namespace2'` - v1Key := model.PolicyKey{Name: ns2 + "/invalid-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: ns2 + "/invalid-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) @@ -146,7 +146,7 @@ var _ = Describe("Test the NetworkPolicy update processor", func() { policy := fullNPv1(ns2) policy.Selector = `((mylabel == 'selectme') && projectcalico.org/namespace == 'namespace2') && all()` - v1Key := model.PolicyKey{Name: ns2 + "/all-sa-selector"} + v1Key := model.PolicyKey{Tier: "default", Name: ns2 + "/all-sa-selector"} Expect(kvps).To(Equal([]*model.KVPair{{Key: v1Key, Value: &policy, Revision: testRev}})) }) }) @@ -187,7 +187,7 @@ var ( tcp = numorstring.ProtocolFromStringV1("tcp") expected1 = []*model.KVPair{ { - Key: model.PolicyKey{Name: "default/knp.default.test.policy"}, + Key: model.PolicyKey{Tier: "default", Name: "default/knp.default.test.policy"}, Value: &model.Policy{ Namespace: "default", Order: &testDefaultPolicyOrder, @@ -232,7 +232,10 @@ var np2 = networkingv1.NetworkPolicy{ var expected2 = []*model.KVPair{ { - Key: model.PolicyKey{Name: "default/knp.default.test.policy"}, + Key: model.PolicyKey{ + Name: "default/knp.default.test.policy", + Tier: "default", + }, Value: &model.Policy{ Namespace: "default", Order: &testDefaultPolicyOrder, @@ -252,7 +255,7 @@ var expected2 = []*model.KVPair{ }, } -var _ = Describe("Test the Kubernetes NetworkPolicy end-to-end conversion and updateprocessor logic", func() { +var _ = Describe("Test the NetworkPolicy update processor + conversion", func() { up := updateprocessors.NewNetworkPolicyUpdateProcessor() DescribeTable("NetworkPolicy update processor + conversion tests", diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor.go index 179d47943e5..76ada499bf5 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ func (pup *profileUpdateProcessor) Process(kvp *model.KVPair) ([]*model.KVPair, Name: v3key.Name, } - v1labelsKey := model.ProfileLabelsKey{pk} - v1rulesKey := model.ProfileRulesKey{pk} + v1labelsKey := model.ProfileLabelsKey{ProfileKey: pk} + v1rulesKey := model.ProfileRulesKey{ProfileKey: pk} v3kvp := *kvp var v1profile *model.Profile @@ -110,12 +110,12 @@ func convertProfileV2ToV1Value(val interface{}) (*model.Profile, error) { var irules []model.Rule for _, irule := range v3res.Spec.Ingress { - irules = append(irules, RuleAPIV2ToBackend(irule, "")) + irules = append(irules, RuleAPIV3ToBackend(irule, "")) } var erules []model.Rule for _, erule := range v3res.Spec.Egress { - erules = append(erules, RuleAPIV2ToBackend(erule, "")) + erules = append(erules, RuleAPIV3ToBackend(erule, "")) } rules := model.ProfileRules{ diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor_test.go index 9ebcb4352ea..2382eba1171 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/profileprocessor_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -61,12 +61,12 @@ var _ = Describe("Test the Profile update processor", func() { Expect(err).NotTo(HaveOccurred()) Expect(kvps).To(HaveLen(3)) Expect(kvps[0]).To(Equal(&model.KVPair{ - Key: model.ProfileLabelsKey{v1ProfileKey1}, + Key: model.ProfileLabelsKey{ProfileKey: v1ProfileKey1}, Value: map[string]string{"testLabel": "label"}, Revision: "abcde", })) Expect(kvps[1]).To(Equal(&model.KVPair{ - Key: model.ProfileRulesKey{v1ProfileKey1}, + Key: model.ProfileRulesKey{ProfileKey: v1ProfileKey1}, Value: nilRules, Revision: "abcde", })) @@ -161,16 +161,16 @@ var _ = Describe("Test the Profile update processor", func() { }) Expect(err).NotTo(HaveOccurred()) - v1irule := updateprocessors.RuleAPIV2ToBackend(irule, "") - v1erule := updateprocessors.RuleAPIV2ToBackend(erule, "") + v1irule := updateprocessors.RuleAPIV3ToBackend(irule, "") + v1erule := updateprocessors.RuleAPIV3ToBackend(erule, "") Expect(kvps).To(HaveLen(3)) Expect(kvps[0]).To(Equal(&model.KVPair{ - Key: model.ProfileLabelsKey{v1ProfileKey2}, + Key: model.ProfileLabelsKey{ProfileKey: v1ProfileKey2}, Value: map[string]string{"testLabel": "label2"}, Revision: "1234", })) Expect(kvps[1]).To(Equal(&model.KVPair{ - Key: model.ProfileRulesKey{v1ProfileKey2}, + Key: model.ProfileRulesKey{ProfileKey: v1ProfileKey2}, Value: &model.ProfileRules{ InboundRules: []model.Rule{v1irule}, OutboundRules: []model.Rule{v1erule}, @@ -186,11 +186,11 @@ var _ = Describe("Test the Profile update processor", func() { Expect(err).NotTo(HaveOccurred()) Expect(kvps).To(Equal([]*model.KVPair{ { - Key: model.ProfileLabelsKey{v1ProfileKey1}, + Key: model.ProfileLabelsKey{ProfileKey: v1ProfileKey1}, Value: nil, }, { - Key: model.ProfileRulesKey{v1ProfileKey1}, + Key: model.ProfileRulesKey{ProfileKey: v1ProfileKey1}, Value: nil, }, { @@ -226,11 +226,11 @@ var _ = Describe("Test the Profile update processor", func() { Expect(err).NotTo(HaveOccurred()) Expect(kvps).To(Equal([]*model.KVPair{ { - Key: model.ProfileLabelsKey{v1ProfileKey1}, + Key: model.ProfileLabelsKey{ProfileKey: v1ProfileKey1}, Value: nil, }, { - Key: model.ProfileRulesKey{v1ProfileKey1}, + Key: model.ProfileRulesKey{ProfileKey: v1ProfileKey1}, Value: nil, }, { diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/rules.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/rules.go index 1ea7997ac0f..8f3d66d86ff 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/rules.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/rules.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,14 +29,14 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/selector/parser" ) -func RulesAPIV2ToBackend(ars []apiv3.Rule, ns string) []model.Rule { +func RulesAPIV3ToBackend(ars []apiv3.Rule, ns string) []model.Rule { if len(ars) == 0 { return nil } brs := make([]model.Rule, len(ars)) for idx, ar := range ars { - brs[idx] = RuleAPIV2ToBackend(ar, ns) + brs[idx] = RuleAPIV3ToBackend(ar, ns) } return brs } @@ -127,7 +127,7 @@ func getEndpointSelector(namespaceSelector, endpointSelector, serviceAccountSele } // RuleAPIToBackend converts an API Rule structure to a Backend Rule structure. -func RuleAPIV2ToBackend(ar apiv3.Rule, ns string) model.Rule { +func RuleAPIV3ToBackend(ar apiv3.Rule, ns string) model.Rule { var icmpCode, icmpType, notICMPCode, notICMPType *int if ar.ICMP != nil { icmpCode = ar.ICMP.Code @@ -163,7 +163,7 @@ func RuleAPIV2ToBackend(ar apiv3.Rule, ns string) model.Rule { } r := model.Rule{ - Action: ruleActionAPIV2ToBackend(ar.Action), + Action: ruleActionAPIV3ToBackend(ar.Action), IPVersion: ar.IPVersion, Protocol: convertV3ProtocolToV1(ar.Protocol), ICMPCode: icmpCode, @@ -284,9 +284,9 @@ func NormalizeIPNets(nets []string) []*cnet.IPNet { return out } -// ruleActionAPIV2ToBackend converts the rule action field value from the API +// ruleActionAPIV3ToBackend converts the rule action field value from the API // value to the equivalent backend value. -func ruleActionAPIV2ToBackend(action apiv3.Action) string { +func ruleActionAPIV3ToBackend(action apiv3.Action) string { if action == apiv3.Pass { return "next-tier" } diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/rules_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/rules_test.go index 4509f04482c..fdc362b9617 100644 --- a/libcalico-go/lib/backend/syncersv1/updateprocessors/rules_test.go +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/rules_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -77,7 +77,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { Annotations: map[string]string{"fizz": "buzz"}}, } // Correct inbound rule - rulev1 := updateprocessors.RuleAPIV2ToBackend(irule, "namespace2") + rulev1 := updateprocessors.RuleAPIV3ToBackend(irule, "namespace2") // Assert we don't change the original protocol. Expect(irule.Protocol.String()).To(Equal("TCP")) @@ -161,7 +161,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { }, } // Correct outbound rule - rulev1 = updateprocessors.RuleAPIV2ToBackend(erule, "") + rulev1 = updateprocessors.RuleAPIV3ToBackend(erule, "") Expect(rulev1.IPVersion).To(Equal(&v4)) Expect(rulev1.Protocol).To(Equal(&eproto)) Expect(rulev1.ICMPCode).To(Equal(&ecode)) @@ -197,7 +197,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { Expect(rulev1.OriginalDstServiceAccountNames).To(BeNil()) By("Converting multiple rules") - rulesv1 := updateprocessors.RulesAPIV2ToBackend([]apiv3.Rule{irule, erule}, "namespace1") + rulesv1 := updateprocessors.RulesAPIV3ToBackend([]apiv3.Rule{irule, erule}, "namespace1") rulev1 = rulesv1[0] Expect(rulev1.Action).To(Equal("allow")) Expect(rulev1.IPVersion).To(Equal(&v4)) @@ -278,7 +278,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "") expected := "has(foo)" By("generating the correct source selector", func() { @@ -306,7 +306,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "") By("generating an empty source selector", func() { Expect(rulev1.SrcSelector).To(Equal("")) @@ -340,7 +340,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "namespace") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "namespace") expected := "(pcns.key == \"value\") && (projectcalico.org/orchestrator == 'k8s')" By("generating the correct source selector", func() { @@ -367,7 +367,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "namespace") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "namespace") By("generating the correct source selector", func() { Expect(rulev1.SrcSelector).To(Equal(e)) @@ -400,7 +400,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "namespace") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "namespace") By("generating the correct source selector", func() { Expect(rulev1.SrcSelector).To(Equal(srce)) @@ -427,7 +427,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "") By("generating the correct source selector", func() { Expect(rulev1.SrcSelector).To(Equal(srce)) @@ -444,7 +444,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "") By("generating an empty source selector", func() { Expect(rulev1.SrcSelector).To(Equal("")) @@ -463,7 +463,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "") By("generating an empty source selector", func() { Expect(rulev1.SrcSelector).To(Equal("")) @@ -487,7 +487,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "") By("generating an empty destination selector", func() { Expect(rulev1.DstSelector).To(Equal("")) @@ -515,7 +515,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { } // Process the rule and get the corresponding v1 representation. - rulev1 := updateprocessors.RuleAPIV2ToBackend(r, "namespace") + rulev1 := updateprocessors.RuleAPIV3ToBackend(r, "namespace") By("generating the correct destination selector", func() { Expect(rulev1.DstSelector).To(Equal(dste)) @@ -547,7 +547,7 @@ var _ = Describe("Test the Rules Conversion Functions", func() { }, } - outRules := updateprocessors.RulesAPIV2ToBackend(rules, "namespace") + outRules := updateprocessors.RulesAPIV3ToBackend(rules, "namespace") // The first rule should select "namespace `red`, the second rule should have 'has(projectcalico.org/namespace)' // and third rule should select '!has(projectcalico.org/namespace)' Expect(outRules[0].DstSelector).To(Equal("(pcns.namespace == \"red\") && (has(label1))")) diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/tierprocessor.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/tierprocessor.go new file mode 100644 index 00000000000..91086a1b03e --- /dev/null +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/tierprocessor.go @@ -0,0 +1,56 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package updateprocessors + +import ( + "errors" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" + "github.com/projectcalico/calico/libcalico-go/lib/backend/watchersyncer" +) + +// Create a new SyncerUpdateProcessor to sync Tiers data in v1 format for +// consumption by Felix. +func NewTierUpdateProcessor() watchersyncer.SyncerUpdateProcessor { + return NewSimpleUpdateProcessor(apiv3.KindTier, ConvertTierV3ToV1Key, ConvertTierV3ToV1Value) +} + +func ConvertTierV3ToV1Key(v3key model.ResourceKey) (model.Key, error) { + if v3key.Name == "" { + return model.PolicyKey{}, errors.New("Missing Name or Namespace field to create a v1 Tier Key") + } + return model.TierKey{ + Name: v3key.Name, + }, nil + +} + +func ConvertTierV3ToV1Value(val interface{}) (interface{}, error) { + v3res, ok := val.(*apiv3.Tier) + if !ok { + return nil, errors.New("Value is not a valid Tier resource value") + } + // Any value except Pass is interpreted as Deny. + action := apiv3.Deny + if v3res.Spec.DefaultAction != nil && *v3res.Spec.DefaultAction == apiv3.Pass { + action = apiv3.Pass + } + return &model.Tier{ + Order: v3res.Spec.Order, + DefaultAction: action, + }, nil +} diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/tierprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/tierprocessor_test.go new file mode 100644 index 00000000000..0ec134c7891 --- /dev/null +++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/tierprocessor_test.go @@ -0,0 +1,150 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package updateprocessors_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" + "github.com/projectcalico/calico/libcalico-go/lib/backend/syncersv1/updateprocessors" + cnet "github.com/projectcalico/calico/libcalico-go/lib/net" +) + +var _ = Describe("Test the Tier update processor", func() { + name1 := "tier1" + name2 := "tier2" + + v3TierKey1 := model.ResourceKey{ + Kind: apiv3.KindTier, + Name: name1, + } + v3TierKey2 := model.ResourceKey{ + Kind: apiv3.KindTier, + Name: name2, + } + v1TierKey1 := model.TierKey{ + Name: name1, + } + v1TierKey2 := model.TierKey{ + Name: name2, + } + + It("should handle conversion of valid Tiers", func() { + up := updateprocessors.NewTierUpdateProcessor() + + By("converting a Tier with minimum configuration") + res := apiv3.NewTier() + + kvps, err := up.Process(&model.KVPair{ + Key: v3TierKey1, + Value: res, + Revision: "abcde", + }) + Expect(err).NotTo(HaveOccurred()) + Expect(kvps).To(HaveLen(1)) + Expect(kvps[0]).To(Equal(&model.KVPair{ + Key: v1TierKey1, + Value: &model.Tier{DefaultAction: apiv3.Deny}, + Revision: "abcde", + })) + + By("adding another Tier with a full configuration") + res = apiv3.NewTier() + + order := float64(101) + aciontPass := apiv3.Pass + + res.Spec.Order = &order + res.Spec.DefaultAction = &aciontPass + kvps, err = up.Process(&model.KVPair{ + Key: v3TierKey2, + Value: res, + Revision: "1234", + }) + Expect(err).NotTo(HaveOccurred()) + + Expect(kvps).To(Equal([]*model.KVPair{ + { + Key: v1TierKey2, + Value: &model.Tier{ + Order: &order, + DefaultAction: apiv3.Pass, + }, + Revision: "1234", + }, + })) + + By("deleting the first tier") + kvps, err = up.Process(&model.KVPair{ + Key: v3TierKey1, + Value: nil, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(kvps).To(Equal([]*model.KVPair{ + { + Key: v1TierKey1, + Value: nil, + }, + })) + }) + + It("should fail to convert an invalid resource", func() { + up := updateprocessors.NewTierUpdateProcessor() + + By("trying to convert with the wrong key type") + res := apiv3.NewTier() + + _, err := up.Process(&model.KVPair{ + Key: model.GlobalBGPPeerKey{ + PeerIP: cnet.MustParseIP("1.2.3.4"), + }, + Value: res, + Revision: "abcde", + }) + Expect(err).To(HaveOccurred()) + + By("trying to convert with the wrong value type") + wres := apiv3.NewHostEndpoint() + + kvps, err := up.Process(&model.KVPair{ + Key: v3TierKey1, + Value: wres, + Revision: "abcde", + }) + Expect(err).NotTo(HaveOccurred()) + Expect(kvps).To(Equal([]*model.KVPair{ + { + Key: v1TierKey1, + Value: nil, + }, + })) + + By("trying to convert without enough information to create a v1 key") + eres := apiv3.NewTier() + v3TierKeyEmpty := model.ResourceKey{ + Kind: apiv3.KindTier, + } + + _, err = up.Process(&model.KVPair{ + Key: v3TierKeyEmpty, + Value: eres, + Revision: "abcde", + }) + Expect(err).To(HaveOccurred()) + }) +}) diff --git a/libcalico-go/lib/backend/watchersyncer/watchersyncer_test.go b/libcalico-go/lib/backend/watchersyncer/watchersyncer_test.go index c080d8271fc..a5eec4f4930 100644 --- a/libcalico-go/lib/backend/watchersyncer/watchersyncer_test.go +++ b/libcalico-go/lib/backend/watchersyncer/watchersyncer_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,9 +23,8 @@ import ( "github.com/google/uuid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" - apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + log "github.com/sirupsen/logrus" kerrors "k8s.io/apimachinery/pkg/api/errors" "github.com/projectcalico/calico/libcalico-go/lib/backend/api" @@ -1013,47 +1012,38 @@ func (c *fakeClient) getLatestWatchRevision() string { // a fake watcher that the test code will drive. func (c *fakeClient) Create(ctx context.Context, object *model.KVPair) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) Update(ctx context.Context, object *model.KVPair) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) Apply(ctx context.Context, object *model.KVPair) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) DeleteKVP(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) Delete(ctx context.Context, key model.Key, revision string) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) Get(ctx context.Context, key model.Key, revision string) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) Syncer(callbacks api.SyncerCallbacks) api.Syncer { panic("should not be called") - return nil } func (c *fakeClient) EnsureInitialized() error { panic("should not be called") - return nil } func (c *fakeClient) Clean() error { panic("should not be called") - return nil } func (c *fakeClient) List(ctx context.Context, list model.ListInterface, revision string) (*model.KVPairList, error) { diff --git a/libcalico-go/lib/client/client.go b/libcalico-go/lib/client/client.go index 2664688a673..83f8c409a92 100644 --- a/libcalico-go/lib/client/client.go +++ b/libcalico-go/lib/client/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -66,6 +66,11 @@ func NewFromEnv() (*Client, error) { return New(*config) } +// Tiers returns an interface for managing tier resources. +func (c *Client) Tiers() TierInterface { + return newTiers(c) +} + // Nodes returns an interface for managing node resources. func (c *Client) Nodes() NodeInterface { return newNodes(c) diff --git a/libcalico-go/lib/client/doc.go b/libcalico-go/lib/client/doc.go index c05b0c2cd6a..d185e2e665b 100644 --- a/libcalico-go/lib/client/doc.go +++ b/libcalico-go/lib/client/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ definitions for each resource type are defined in the following package: The client has a number of methods that return interfaces for managing: - BGP Peer resources + - Tier resources - Policy resources - IP Pool resources - Host endpoint resources @@ -37,77 +38,70 @@ resource type. The resource management interfaces have a common set of commands to create, delete, update and retrieve resource instances. For example, an application using this -client to manage host endpoint resources would create an instance of this client, create a -new HostEndpoints interface and call the appropriate methods on that interface. For example: +client to manage tier resources would create an instance of this client, create a +new Tiers interface and call the appropriate methods on that interface. For example: // NewFromEnv() creates a new client and defaults to access an etcd backend datastore at // http://127.0.0.1:2379. For alternative backend access details, set the appropriate // ENV variables specified in the CalicoAPIConfigSpec structure. - client, err := client.NewFromEnv() + clientv3, err := clientv3.NewFromEnv() - // Obtain the interface for managing host endpoint resources. - hostendpoints := client.HostEndpoints() + // Obtain the interface for managing tier resources. + tiers := clientv3.Tiers() - // Create a new host endpoint. All Create() methods return an error of type + // Create a new tier. All Create() methods return an error of type // common.ErrorResourceAlreadyExists if the resource specified by its // unique identifiers already exists. - hostEndpoint, err := hostEndpoints.Create(&api.HostEndpoint{ - Metadata: api.HostEndpointMetadata{ - Name: "endpoint1", - Nodename: "hostname1", + tier, err := tiers.Create(&apiv3.Tier{ + Metadata: apiv3.TierMetadata{ + Name: "tier-1", }, - Spec: api.HostEndpointSpec{ - InterfaceName: "eth0" + Spec: apiv3.TierSpec{ + Order: 100 }, } - // Update an existing host endpoint. All Update() methods return an error of type + // Update am existing tier. All Update() methods return an error of type // common.ErrorResourceDoesNotExist if the resource specified by its // unique identifiers does not exist. - hostEndpoint, err = hostEndpoints.Update(&api.HostEndpoint{ - Metadata: api.HostEndpointMetadata{ - Name: "endpoint1", - Nodename: "hostname1", + tier, err = tiers.Update(&apiv3.Tier{ + Metadata: apiv3.TierMetadata{ + Name: "tier-1", }, - Spec: api.HostEndpointSpec{ - InterfaceName: "eth0", - Profiles: []string{"profile1"}, + Spec: apiv3.TierSpec{ + Order: 200 }, } - // Apply (update or create) a hostEndpoint. All Apply() methods will update a resource + // Apply (update or create) a tier. All Apply() methods will update a resource // if it already exists, and will create a new resource if it does not. - hostEndpoint, err = hostEndpoints.Apply(&api.HostEndpoint{ - Metadata: api.HostEndpointMetadata{ - Name: "endpoint1", - Nodename: "hostname1", + tier, err = tiers.Apply(&apiv3.Tier{ + Metadata: apiv3.TierMetadata{ + Name: "tier-2", }, - Spec: api.HostEndpointSpec{ - InterfaceName: "eth1", - Profiles: []string{"profile1"}, + Spec: apiv3.TierSpec{ + Order: 150 }, } - // Delete a hostEndpoint. All Delete() methods return an error of type + // Delete a tier. All Delete() methods return an error of type // common.ErrorResourceDoesNotExist if the resource specified by its // unique identifiers does not exist. - hostEndpoint, err = hostEndpoints.Delete(api.HostEndpointMetadata{ - Name: "endpoint1", - Nodename: "hostname1", + tier, err = tiers.Delete(apiv3.TierMetadata{ + Name: "tier-2", }) - // Get a hostEndpoint. All Get() methods return an error of type + // Get a tier. All Get() methods return an error of type // common.ErrorResourceDoesNotExist if the resource specified by its // unique identifiers does not exist. - hostEndpoint, err = hostEndpoints.Get(api.HostEndpointMetadata{ - Name: "endpoint1", - Nodename: "hostname1", + tier, err = tiers.Get(apiv3.TierMetadata{ + Name: "tier-2", }) - // List all hostEndpoints. All List() methods take a (sub-)set of the resource + // List all tiers. All List() methods take a (sub-)set of the resource // identifiers and return the corresponding list resource type that has an // Items field containing a list of resources that match the supplied // identifiers. - hostEndpointList, err := hostEndpoints.List(api.HostEndpointMetadata{}) + tierList, err := tiers.List(apiv3.TierMetadata{}) */ package client diff --git a/libcalico-go/lib/client/node.go b/libcalico-go/lib/client/node.go index 2a232f1a953..b1e8cee7343 100644 --- a/libcalico-go/lib/client/node.go +++ b/libcalico-go/lib/client/node.go @@ -151,11 +151,11 @@ func (h *nodes) convertAPIToKVPair(a unversioned.Resource) (*model.KVPair, error v := model.Node{} if an.Spec.BGP != nil { if an.Spec.BGP.IPv4Address != nil { - v.BGPIPv4Addr = &net.IP{an.Spec.BGP.IPv4Address.IP} + v.BGPIPv4Addr = &net.IP{IP: an.Spec.BGP.IPv4Address.IP} v.BGPIPv4Net = an.Spec.BGP.IPv4Address.Network() } if an.Spec.BGP.IPv6Address != nil { - v.BGPIPv6Addr = &net.IP{an.Spec.BGP.IPv6Address.IP} + v.BGPIPv6Addr = &net.IP{IP: an.Spec.BGP.IPv6Address.IP} v.BGPIPv6Net = an.Spec.BGP.IPv6Address.Network() } v.BGPASNumber = an.Spec.BGP.ASNumber diff --git a/libcalico-go/lib/client/policy.go b/libcalico-go/lib/client/policy.go index 9436985f5bd..a031793eed7 100644 --- a/libcalico-go/lib/client/policy.go +++ b/libcalico-go/lib/client/policy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,6 +19,14 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" "github.com/projectcalico/calico/libcalico-go/lib/converter" + "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" +) + +var ( + defaultTier = api.Tier{ + Metadata: api.TierMetadata{Name: names.DefaultTierName}, + } ) // PolicyInterface has methods to work with Policy resources. @@ -44,6 +52,18 @@ func newPolicies(c *Client) *policies { // Create creates a new policy. func (h *policies) Create(a *api.Policy) (*api.Policy, error) { + // Before creating the policy, check that the tier exists, and if this is the + // default tier, create it if it doesn't. + if a.Metadata.Tier == "" { + if _, err := h.c.Tiers().Create(&defaultTier); err != nil { + if _, ok := err.(errors.ErrorResourceAlreadyExists); !ok { + return nil, err + } + } + } else if _, err := h.c.Tiers().Get(api.TierMetadata{Name: a.Metadata.Tier}); err != nil { + return nil, err + } + return a, h.c.create(*a, h) } @@ -54,6 +74,18 @@ func (h *policies) Update(a *api.Policy) (*api.Policy, error) { // Apply updates a policy if it exists, or creates a new policy if it does not exist. func (h *policies) Apply(a *api.Policy) (*api.Policy, error) { + // Before creating the policy, check that the tier exists, and if this is the + // default tier, create it if it doesn't. + if a.Metadata.Tier == "" { + if _, err := h.c.Tiers().Create(&defaultTier); err != nil { + if _, ok := err.(errors.ErrorResourceAlreadyExists); !ok { + return nil, err + } + } + } else if _, err := h.c.Tiers().Get(api.TierMetadata{Name: a.Metadata.Tier}); err != nil { + return nil, err + } + return a, h.c.apply(*a, h) } @@ -85,6 +117,7 @@ func (h *policies) convertMetadataToListInterface(m unversioned.ResourceMetadata pm := m.(api.PolicyMetadata) l := model.PolicyListOptions{ Name: pm.Name, + Tier: pm.Tier, } return l, nil } diff --git a/libcalico-go/lib/client/tier.go b/libcalico-go/lib/client/tier.go new file mode 100644 index 00000000000..501aff9cce2 --- /dev/null +++ b/libcalico-go/lib/client/tier.go @@ -0,0 +1,132 @@ +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + api "github.com/projectcalico/calico/libcalico-go/lib/apis/v1" + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" +) + +// TierInterface has methods to work with Tier resources. +type TierInterface interface { + List(api.TierMetadata) (*api.TierList, error) + Get(api.TierMetadata) (*api.Tier, error) + Create(*api.Tier) (*api.Tier, error) + Update(*api.Tier) (*api.Tier, error) + Apply(*api.Tier) (*api.Tier, error) + Delete(api.TierMetadata) error +} + +// tiers implements TierInterface +type tiers struct { + c *Client +} + +// newTiers returns a new TierInterface bound to the supplied client. +func newTiers(c *Client) TierInterface { + return &tiers{c} +} + +// Create creates a new tier. +func (h *tiers) Create(a *api.Tier) (*api.Tier, error) { + return a, h.c.create(*a, h) +} + +// Update updates an existing tier. +func (h *tiers) Update(a *api.Tier) (*api.Tier, error) { + return a, h.c.update(*a, h) +} + +// Apply updates a tier if it exists, or creates a new tier if it does not exist. +func (h *tiers) Apply(a *api.Tier) (*api.Tier, error) { + return a, h.c.apply(*a, h) +} + +// Delete deletes an existing tier. +func (h *tiers) Delete(metadata api.TierMetadata) error { + return h.c.delete(metadata, h) +} + +// Get returns information about a particular tier. +func (h *tiers) Get(metadata api.TierMetadata) (*api.Tier, error) { + if a, err := h.c.get(metadata, h); err != nil { + return nil, err + } else { + return a.(*api.Tier), nil + } +} + +// List takes a Metadata, and returns a TierList that contains the list of tiers +// that match the Metadata (wildcarding missing fields). +func (h *tiers) List(metadata api.TierMetadata) (*api.TierList, error) { + l := api.NewTierList() + err := h.c.list(metadata, h, l) + return l, err +} + +// convertMetadataToListInterface converts a TierMetadata to a TierListOptions. +// This is part of the conversionHelper interface. +func (h *tiers) convertMetadataToListInterface(m unversioned.ResourceMetadata) (model.ListInterface, error) { + hm := m.(api.TierMetadata) + l := model.TierListOptions{ + Name: hm.Name, + } + return l, nil +} + +// convertMetadataToKey converts a TierMetadata to a TierKey +// This is part of the conversionHelper interface. +func (h *tiers) convertMetadataToKey(m unversioned.ResourceMetadata) (model.Key, error) { + hm := m.(api.TierMetadata) + k := model.TierKey{ + Name: hm.Name, + } + return k, nil +} + +// convertAPIToKVPair converts an API Tier structure to a KVPair containing a +// backend Tier and TierKey. +// This is part of the conversionHelper interface. +func (h *tiers) convertAPIToKVPair(a unversioned.Resource) (*model.KVPair, error) { + at := a.(api.Tier) + k, err := h.convertMetadataToKey(at.Metadata) + if err != nil { + return nil, err + } + + d := model.KVPair{ + Key: k, + Value: &model.Tier{ + Order: at.Spec.Order, + }, + } + + return &d, nil +} + +// convertKVPairToAPI converts a KVPair containing a backend Tier and TierKey +// to an API Tier structure. +// This is part of the conversionHelper interface. +func (h *tiers) convertKVPairToAPI(d *model.KVPair) (unversioned.Resource, error) { + bt := d.Value.(*model.Tier) + bk := d.Key.(model.TierKey) + + at := api.NewTier() + at.Metadata.Name = bk.Name + at.Spec.Order = bt.Order + + return at, nil +} diff --git a/libcalico-go/lib/clientv3/client.go b/libcalico-go/lib/clientv3/client.go index e19086926b4..42e1d279391 100644 --- a/libcalico-go/lib/clientv3/client.go +++ b/libcalico-go/lib/clientv3/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/google/uuid" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" @@ -32,6 +33,7 @@ import ( bapi "github.com/projectcalico/calico/libcalico-go/lib/backend/api" cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" "github.com/projectcalico/calico/libcalico-go/lib/ipam" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/net" "github.com/projectcalico/calico/libcalico-go/lib/options" "github.com/projectcalico/calico/libcalico-go/lib/set" @@ -129,6 +131,11 @@ func (c client) BGPPeers() BGPPeerInterface { return bgpPeers{client: c} } +// Tiers returns an interface for managing tier resources. +func (c client) Tiers() TierInterface { + return tiers{client: c} +} + // IPAM returns an interface for managing IP address assignment and releasing. func (c client) IPAM() ipam.Interface { return ipam.NewIPAMClient(c.backend, poolAccessor{client: &c}, c.IPReservations()) @@ -220,19 +227,43 @@ func (p poolAccessor) GetAllPools() ([]v3.IPPool, error) { // EnsureInitialized is used to ensure the backend datastore is correctly // initialized for use by Calico. This method may be called multiple times, and -// will have no effect if the datastore is already correctly initialized. +// will have no effect if the datastore is already correctly initialized. This method +// is fail-slow in that it does as much initialization as it can, only returning error +// after attempting all initialization steps - this allows partial initialization for +// components that have restricted access to the Calico resources (mainly a KDD thing). // // Most Calico deployment scenarios will automatically implicitly invoke this // method and so a general consumer of this API can assume that the datastore // is already initialized. func (c client) EnsureInitialized(ctx context.Context, calicoVersion, clusterType string) error { + var errs []error + // Perform datastore specific initialization first. if err := c.backend.EnsureInitialized(); err != nil { - return err + log.WithError(err).Info("Unable to initialize backend datastore") + errs = append(errs, err) } if err := c.ensureClusterInformation(ctx, calicoVersion, clusterType); err != nil { - return err + log.WithError(err).Info("Unable to initialize ClusterInformation") + errs = append(errs, err) + } + + if err := c.ensureDefaultTierExists(ctx); err != nil { + log.WithError(err).Info("Unable to initialize default Tier") + errs = append(errs, err) + } + + if err := c.ensureAdminNetworkPolicyTierExists(ctx); err != nil { + log.WithError(err).Info("Unable to initialize adminnetworkpolicy Tier") + errs = append(errs, err) + } + + // If there are any errors return the first error. We could combine the error text here and return + // a generic error, but an application may be expecting a certain error code, so best just return + // the original error. + if len(errs) > 0 { + return errs[0] } return nil @@ -364,6 +395,46 @@ func (c client) ensureClusterInformation(ctx context.Context, calicoVersion, clu return nil } +// ensureDefaultTierExists ensures that the "default" Tier exits in the datastore. +// This is done by trying to create the default tier. If it doesn't exists, it +// is created. A error is returned if there is any error other than when the +// default tier resource already exists. +func (c client) ensureDefaultTierExists(ctx context.Context) error { + order := v3.DefaultTierOrder + defaultTier := v3.NewTier() + defaultTier.ObjectMeta = metav1.ObjectMeta{Name: names.DefaultTierName} + defaultTier.Spec = v3.TierSpec{ + Order: &order, + } + if _, err := c.Tiers().Create(ctx, defaultTier, options.SetOptions{}); err != nil { + if _, ok := err.(cerrors.ErrorResourceAlreadyExists); !ok { + return err + } + } + return nil +} + +// ensureAdminNetworkPolicyTierExists ensures that the "adminnetworkpolicy" Tier exits in the datastore. +// This is done by trying to create the adminnetworkpolicy tier. If it doesn't exists, it +// is created. A error is returned if there is any error other than when the +// tier resource already exists. +func (c client) ensureAdminNetworkPolicyTierExists(ctx context.Context) error { + order := v3.AdminNetworkPolicyTierOrder + actionPass := v3.Pass + anpTier := v3.NewTier() + anpTier.ObjectMeta = metav1.ObjectMeta{Name: names.AdminNetworkPolicyTierName} + anpTier.Spec = v3.TierSpec{ + Order: &order, + DefaultAction: &actionPass, + } + if _, err := c.Tiers().Create(ctx, anpTier, options.SetOptions{}); err != nil { + if _, ok := err.(cerrors.ErrorResourceAlreadyExists); !ok { + return err + } + } + return nil +} + // Backend returns the backend client used by the v3 client. Not exposed on the main // client API, but available publicly for consumers that require access to the backend // client (e.g. for syncer support). diff --git a/libcalico-go/lib/clientv3/common_test.go b/libcalico-go/lib/clientv3/common_test.go index 7c54d4cb653..bcc51a20c8c 100644 --- a/libcalico-go/lib/clientv3/common_test.go +++ b/libcalico-go/lib/clientv3/common_test.go @@ -57,7 +57,7 @@ var _ = testutils.E2eDatastoreDescribe("Common resource tests", testutils.Datast By("Creating a new IPPool with name1/spec1 and expecting CreationTimestamp nanoseconds to be stripped off") now := time.Now() res1, outError := c.IPPools().Create(ctx, &apiv3.IPPool{ - ObjectMeta: metav1.ObjectMeta{Name: name1, CreationTimestamp: metav1.Time{now}}, + ObjectMeta: metav1.ObjectMeta{Name: name1, CreationTimestamp: metav1.Time{Time: now}}, Spec: spec1, }, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) diff --git a/libcalico-go/lib/clientv3/doc.go b/libcalico-go/lib/clientv3/doc.go index 10f61e93dc1..1cb8a8ece69 100644 --- a/libcalico-go/lib/clientv3/doc.go +++ b/libcalico-go/lib/clientv3/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ The client has a number of methods that return interfaces for managing: - Host endpoint resources - Workload endpoint resources - Profile resources + - Tier resources - IP Address Management (IPAM) See [resource definitions](http://docs.projectcalico.org/latest/reference/calicoctl/resources/) for details about the set of management commands for each diff --git a/libcalico-go/lib/clientv3/globalnetworkpolicy.go b/libcalico-go/lib/clientv3/globalnetworkpolicy.go index 75fab314f83..b58eaeb463b 100644 --- a/libcalico-go/lib/clientv3/globalnetworkpolicy.go +++ b/libcalico-go/lib/clientv3/globalnetworkpolicy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,13 +16,15 @@ package clientv3 import ( "context" - "strings" apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" validator "github.com/projectcalico/calico/libcalico-go/lib/validator/v3" "github.com/projectcalico/calico/libcalico-go/lib/watch" + + log "github.com/sirupsen/logrus" ) // GlobalNetworkPolicyInterface has methods to work with GlobalNetworkPolicy resources. @@ -43,6 +45,13 @@ type globalNetworkPolicies struct { // Create takes the representation of a GlobalNetworkPolicy and creates it. Returns the stored // representation of the GlobalNetworkPolicy, and an error, if there is any. func (r globalNetworkPolicies) Create(ctx context.Context, res *apiv3.GlobalNetworkPolicy, opts options.SetOptions) (*apiv3.GlobalNetworkPolicy, error) { + // Before creating the policy, check that the tier exists. + tier := names.TierOrDefault(res.Spec.Tier) + if _, err := r.client.resources.Get(ctx, options.GetOptions{}, apiv3.KindTier, noNamespace, tier); err != nil { + log.WithError(err).Infof("Tier %v does not exist", tier) + return nil, err + } + if res != nil { // Since we're about to default some fields, take a (shallow) copy of the input data // before we do so. @@ -56,16 +65,27 @@ func (r globalNetworkPolicies) Create(ctx context.Context, res *apiv3.GlobalNetw } // Properly prefix the name - res.GetObjectMeta().SetName(convertPolicyNameForStorage(res.GetObjectMeta().GetName())) + backendPolicyName, err := names.BackendTieredPolicyName(res.GetObjectMeta().GetName(), res.Spec.Tier) + if err != nil { + return nil, err + } + res.GetObjectMeta().SetName(backendPolicyName) + + // Add tier labels to policy for lookup. + if tier != "default" { + res.GetObjectMeta().SetLabels(addTierLabel(res.GetObjectMeta().GetLabels(), tier)) + } + out, err := r.client.resources.Create(ctx, opts, apiv3.KindGlobalNetworkPolicy, res) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) return out.(*apiv3.GlobalNetworkPolicy), err } - // Remove the prefix out of the returned policy name. - res.GetObjectMeta().SetName(convertPolicyNameFromStorage(res.GetObjectMeta().GetName())) + // Add the tier labels if necessary + res.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(res.GetObjectMeta().GetLabels())) + return nil, err } @@ -85,25 +105,38 @@ func (r globalNetworkPolicies) Update(ctx context.Context, res *apiv3.GlobalNetw } // Properly prefix the name - res.GetObjectMeta().SetName(convertPolicyNameForStorage(res.GetObjectMeta().GetName())) + backendPolicyName, err := names.BackendTieredPolicyName(res.GetObjectMeta().GetName(), res.Spec.Tier) + if err != nil { + return nil, err + } + res.GetObjectMeta().SetName(backendPolicyName) + + // Add tier labels to policy for lookup. + tier := names.TierOrDefault(res.Spec.Tier) + if tier != "default" { + res.GetObjectMeta().SetLabels(addTierLabel(res.GetObjectMeta().GetLabels(), tier)) + } + out, err := r.client.resources.Update(ctx, opts, apiv3.KindGlobalNetworkPolicy, res) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) return out.(*apiv3.GlobalNetworkPolicy), err } - // Remove the prefix out of the returned policy name. - res.GetObjectMeta().SetName(convertPolicyNameFromStorage(res.GetObjectMeta().GetName())) + // Add the tier labels if necessary + res.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(res.GetObjectMeta().GetLabels())) + return nil, err } // Delete takes name of the GlobalNetworkPolicy and deletes it. Returns an error if one occurs. func (r globalNetworkPolicies) Delete(ctx context.Context, name string, opts options.DeleteOptions) (*apiv3.GlobalNetworkPolicy, error) { - out, err := r.client.resources.Delete(ctx, opts, apiv3.KindGlobalNetworkPolicy, noNamespace, convertPolicyNameForStorage(name)) + backendPolicyName := names.TieredPolicyName(name) + out, err := r.client.resources.Delete(ctx, opts, apiv3.KindGlobalNetworkPolicy, noNamespace, backendPolicyName) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) return out.(*apiv3.GlobalNetworkPolicy), err } return nil, err @@ -112,11 +145,23 @@ func (r globalNetworkPolicies) Delete(ctx context.Context, name string, opts opt // Get takes name of the GlobalNetworkPolicy, and returns the corresponding GlobalNetworkPolicy object, // and an error if there is any. func (r globalNetworkPolicies) Get(ctx context.Context, name string, opts options.GetOptions) (*apiv3.GlobalNetworkPolicy, error) { - out, err := r.client.resources.Get(ctx, opts, apiv3.KindGlobalNetworkPolicy, noNamespace, convertPolicyNameForStorage(name)) + backendPolicyName := names.TieredPolicyName(name) + out, err := r.client.resources.Get(ctx, opts, apiv3.KindGlobalNetworkPolicy, noNamespace, backendPolicyName) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) - return out.(*apiv3.GlobalNetworkPolicy), err + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) + // Fill in the tier information from the policy name if we find it missing. + // We expect backend policies to have the right name (prefixed with tier name). + res_out := out.(*apiv3.GlobalNetworkPolicy) + if res_out.Spec.Tier == "" { + tier, tierErr := names.TierFromPolicyName(res_out.Name) + if tierErr != nil { + log.WithError(tierErr).Infof("Skipping setting tier for name %v", res_out.Name) + return res_out, tierErr + } + res_out.Spec.Tier = tier + } + return res_out, err } return nil, err } @@ -125,18 +170,27 @@ func (r globalNetworkPolicies) Get(ctx context.Context, name string, opts option func (r globalNetworkPolicies) List(ctx context.Context, opts options.ListOptions) (*apiv3.GlobalNetworkPolicyList, error) { res := &apiv3.GlobalNetworkPolicyList{} // Add the name prefix if name is provided - if opts.Name != "" { - opts.Name = convertPolicyNameForStorage(opts.Name) + if opts.Name != "" && !opts.Prefix { + opts.Name = names.TieredPolicyName(opts.Name) } if err := r.client.resources.List(ctx, opts, apiv3.KindGlobalNetworkPolicy, apiv3.KindGlobalNetworkPolicyList, res); err != nil { return nil, err } - // Remove the prefix off of each policy name + // Make sure the tier labels are added for i, _ := range res.Items { - name := res.Items[i].GetObjectMeta().GetName() - res.Items[i].GetObjectMeta().SetName(convertPolicyNameFromStorage(name)) + res.Items[i].GetObjectMeta().SetLabels(defaultTierLabelIfMissing(res.Items[i].GetObjectMeta().GetLabels())) + // Fill in the tier information from the policy name if we find it missing. + // We expect backend policies to have the right name (prefixed with tier name). + if res.Items[i].Spec.Tier == "" { + tier, tierErr := names.TierFromPolicyName(res.Items[i].Name) + if tierErr != nil { + log.WithError(tierErr).Infof("Skipping setting tier for name %v", res.Items[i].Name) + continue + } + res.Items[i].Spec.Tier = tier + } } return res, nil @@ -147,7 +201,7 @@ func (r globalNetworkPolicies) List(ctx context.Context, opts options.ListOption func (r globalNetworkPolicies) Watch(ctx context.Context, opts options.ListOptions) (watch.Interface, error) { // Add the name prefix if name is provided if opts.Name != "" { - opts.Name = convertPolicyNameForStorage(opts.Name) + opts.Name = names.TieredPolicyName(opts.Name) } return r.client.resources.Watch(ctx, opts, apiv3.KindGlobalNetworkPolicy, &policyConverter{}) @@ -174,34 +228,33 @@ func defaultPolicyTypesField(ingressRules, egressRules []apiv3.Rule, types *[]ap } } -func convertPolicyNameForStorage(name string) string { - // Do nothing on names prefixed with "knp." - if strings.HasPrefix(name, "knp.") { - return name - } - // Similarly for "ossg." - if strings.HasPrefix(name, "ossg.") { - return name +func addTierLabel(labels map[string]string, prefix string) map[string]string { + // Create the map if it is nil + if labels == nil { + labels = make(map[string]string) } - return "default." + name + + labels[apiv3.LabelTier] = prefix + return labels } -func convertPolicyNameFromStorage(name string) string { - // Do nothing on names prefixed with "knp." - if strings.HasPrefix(name, "knp.") { - return name +func defaultTierLabelIfMissing(labels map[string]string) map[string]string { + // Create the map if it is nil + if labels == nil { + labels = make(map[string]string) } - // Similarly for "ossg." - if strings.HasPrefix(name, "ossg.") { - return name + + // Add the default labels if one is not set + if _, ok := labels[apiv3.LabelTier]; !ok { + labels[apiv3.LabelTier] = "default" } - parts := strings.SplitN(name, ".", 2) - return parts[len(parts)-1] + + return labels } type policyConverter struct{} func (pc *policyConverter) Convert(r resource) resource { - r.GetObjectMeta().SetName(convertPolicyNameFromStorage(r.GetObjectMeta().GetName())) + r.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(r.GetObjectMeta().GetLabels())) return r } diff --git a/libcalico-go/lib/clientv3/globalnetworkpolicy_e2e_test.go b/libcalico-go/lib/clientv3/globalnetworkpolicy_e2e_test.go index 7ac8e5f4abd..d6fb8d46c9d 100644 --- a/libcalico-go/lib/clientv3/globalnetworkpolicy_e2e_test.go +++ b/libcalico-go/lib/clientv3/globalnetworkpolicy_e2e_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,12 +27,19 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" "github.com/projectcalico/calico/libcalico-go/lib/backend" + bapi "github.com/projectcalico/calico/libcalico-go/lib/backend/api" "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" "github.com/projectcalico/calico/libcalico-go/lib/testutils" "github.com/projectcalico/calico/libcalico-go/lib/watch" ) +func tieredGNPName(p, t string) string { + name, _ := names.BackendTieredPolicyName(p, t) + return name +} + var ( ingressEgress = []apiv3.PolicyType{apiv3.PolicyTypeIngress, apiv3.PolicyTypeEgress} ingress = []apiv3.PolicyType{apiv3.PolicyTypeIngress} @@ -43,6 +50,9 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da ctx := context.Background() order1 := 99.999 order2 := 22.222 + tier := "tier-a" + tierOrder := float64(10) + actionDeny := apiv3.Deny name1 := "globalnetworkp-1" name2 := "globalnetworkp-2" spec1 := apiv3.GlobalNetworkPolicySpec{ @@ -70,14 +80,38 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da egressTypesSpec2 := spec2 egressTypesSpec2.Types = egress - DescribeTable("GlobalNetworkPolicy e2e CRUD tests", - func(name1, name2 string, spec1, spec2 apiv3.GlobalNetworkPolicySpec, types1, types2 []apiv3.PolicyType) { - c, err := clientv3.New(config) - Expect(err).NotTo(HaveOccurred()) + var c clientv3.Interface + var be bapi.Client - be, err := backend.NewClient(config) - Expect(err).NotTo(HaveOccurred()) - be.Clean() + BeforeEach(func() { + var err error + c, err = clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) + + be, err = backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + err = c.EnsureInitialized(ctx, "", "") + Expect(err).NotTo(HaveOccurred()) + }) + + DescribeTable("GlobalNetworkPolicy e2e CRUD tests", + func(tier, name1, name2 string, spec1, spec2 apiv3.GlobalNetworkPolicySpec, types1, types2 []apiv3.PolicyType) { + spec1.Tier = tier + spec2.Tier = tier + + if tier != "" && tier != "default" { + // Create the tier if required before running other tiered policy tests. + tierSpec := apiv3.TierSpec{Order: &tierOrder, DefaultAction: &actionDeny} + By("Creating the tier") + tierRes, resErr := c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: tier}, + Spec: tierSpec, + }, options.SetOptions{}) + Expect(resErr).NotTo(HaveOccurred()) + Expect(tierRes).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, tier, tierSpec)) + } By("Updating the GlobalNetworkPolicy before it is created") _, outError := c.GlobalNetworkPolicies().Update(ctx, &apiv3.GlobalNetworkPolicy{ @@ -85,7 +119,7 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da Spec: spec1, }, options.SetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(default." + name1 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(" + tieredGNPName(name1, tier) + ") with error:")) By("Attempting to creating a new GlobalNetworkPolicy with name1/spec1 and a non-empty ResourceVersion") polToCreate := &apiv3.GlobalNetworkPolicy{ @@ -108,7 +142,7 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da Expect(polToCreate).To(Equal(polToCreateCopy), "Create() unexpectedly modified input policy") Expect(outError).NotTo(HaveOccurred()) spec1.Types = types1 - Expect(res1).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec1)) + Expect(res1).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec1)) // Track the version of the original data for name1. rv1_1 := res1.ResourceVersion @@ -119,24 +153,24 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da Spec: spec2, }, options.SetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(Equal("resource already exists: GlobalNetworkPolicy(default." + name1 + ")")) + Expect(outError.Error()).To(Equal("resource already exists: GlobalNetworkPolicy(" + tieredGNPName(name1, tier) + ")")) By("Getting GlobalNetworkPolicy (name1) and comparing the output against spec1") res, outError := c.GlobalNetworkPolicies().Get(ctx, name1, options.GetOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec1)) + Expect(res).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec1)) Expect(res.ResourceVersion).To(Equal(res1.ResourceVersion)) By("Getting GlobalNetworkPolicy (name2) before it is created") _, outError = c.GlobalNetworkPolicies().Get(ctx, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(" + tieredGNPName(name2, tier) + ") with error:")) By("Listing all the GlobalNetworkPolicies, expecting a single result with name1/spec1") outList, outError := c.GlobalNetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec1), + testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec1), )) By("Creating a new GlobalNetworkPolicy with name2/spec2") @@ -146,20 +180,20 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da }, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) spec2.Types = types2 - Expect(res2).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name2, spec2)) + Expect(res2).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name2, tier), spec2)) By("Getting GlobalNetworkPolicy (name2) and comparing the output against spec2") res, outError = c.GlobalNetworkPolicies().Get(ctx, name2, options.GetOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(res2).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name2, spec2)) + Expect(res2).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name2, tier), spec2)) Expect(res.ResourceVersion).To(Equal(res2.ResourceVersion)) By("Listing all the GlobalNetworkPolicies, expecting a two results with name1/spec1 and name2/spec2") outList, outError = c.GlobalNetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec1), - testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name2, spec2), + testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec1), + testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name2, tier), spec2), )) By("Updating GlobalNetworkPolicy name1 with spec2") @@ -168,7 +202,7 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da res1out, outError := c.GlobalNetworkPolicies().Update(ctx, res1, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) Expect(res1).To(Equal(res1Copy), "Update() unexpectedly modified input") - Expect(res1).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec2)) + Expect(res1).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec2)) res1 = res1out By("Attempting to update the GlobalNetworkPolicy without a Creation Timestamp") @@ -204,20 +238,20 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da res1.ResourceVersion = rv1_1 _, outError = c.GlobalNetworkPolicies().Update(ctx, res1, options.SetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(Equal("update conflict: GlobalNetworkPolicy(default." + name1 + ")")) + Expect(outError.Error()).To(Equal("update conflict: GlobalNetworkPolicy(" + tieredGNPName(name1, tier) + ")")) if config.Spec.DatastoreType != apiconfig.Kubernetes { By("Getting GlobalNetworkPolicy (name1) with the original resource version and comparing the output against spec1") res, outError = c.GlobalNetworkPolicies().Get(ctx, name1, options.GetOptions{ResourceVersion: rv1_1}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec1)) + Expect(res).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec1)) Expect(res.ResourceVersion).To(Equal(rv1_1)) } By("Getting GlobalNetworkPolicy (name1) with the updated resource version and comparing the output against spec2") res, outError = c.GlobalNetworkPolicies().Get(ctx, name1, options.GetOptions{ResourceVersion: rv1_2}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec2)) + Expect(res).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec2)) Expect(res.ResourceVersion).To(Equal(rv1_2)) if config.Spec.DatastoreType != apiconfig.Kubernetes { @@ -225,7 +259,7 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da outList, outError = c.GlobalNetworkPolicies().List(ctx, options.ListOptions{ResourceVersion: rv1_1}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec1), + testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec1), )) } @@ -233,21 +267,22 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da outList, outError = c.GlobalNetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec2), - testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name2, spec2), + testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec2), + testutils.Resource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name2, tier), spec2), )) if config.Spec.DatastoreType != apiconfig.Kubernetes { By("Deleting GlobalNetworkPolicy (name1) with the old resource version") _, outError = c.GlobalNetworkPolicies().Delete(ctx, name1, options.DeleteOptions{ResourceVersion: rv1_1}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(Equal("update conflict: GlobalNetworkPolicy(default." + name1 + ")")) + Expect(outError.Error()).To(Equal("update conflict: GlobalNetworkPolicy(" + tieredGNPName(name1, tier) + ")")) } By("Deleting GlobalNetworkPolicy (name1) with the new resource version") dres, outError := c.GlobalNetworkPolicies().Delete(ctx, name1, options.DeleteOptions{ResourceVersion: rv1_2}) Expect(outError).NotTo(HaveOccurred()) - Expect(dres).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name1, spec2)) + Expect(dres).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name1, tier), spec2)) + time.Sleep(1 * time.Second) if config.Spec.DatastoreType != apiconfig.Kubernetes { By("Updating GlobalNetworkPolicy name2 with a 2s TTL and waiting for the entry to be deleted") @@ -259,7 +294,7 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da time.Sleep(2 * time.Second) _, outError = c.GlobalNetworkPolicies().Get(ctx, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(" + tieredGNPName(name2, tier) + ") with error:")) By("Creating GlobalNetworkPolicy name2 with a 2s TTL and waiting for the entry to be deleted") _, outError = c.GlobalNetworkPolicies().Create(ctx, &apiv3.GlobalNetworkPolicy{ @@ -273,20 +308,21 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da time.Sleep(2 * time.Second) _, outError = c.GlobalNetworkPolicies().Get(ctx, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(" + tieredGNPName(name2, tier) + ") with error:")) } if config.Spec.DatastoreType == apiconfig.Kubernetes { By("Deleting GlobalNetworkPolicy (name2) for KDD that does not support TTL") dres, outError = c.GlobalNetworkPolicies().Delete(ctx, name2, options.DeleteOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(dres).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, name2, spec2)) + Expect(dres).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, tieredGNPName(name2, tier), spec2)) + time.Sleep(1 * time.Second) } By("Attempting to delete GlobalNetworkPolicy (name2) again") _, outError = c.GlobalNetworkPolicies().Delete(ctx, name2, options.DeleteOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(" + tieredGNPName(name2, tier) + ") with error:")) By("Listing all GlobalNetworkPolicies and expecting no items") outList, outError = c.GlobalNetworkPolicies().List(ctx, options.ListOptions{}) @@ -296,26 +332,21 @@ var _ = testutils.E2eDatastoreDescribe("GlobalNetworkPolicy tests", testutils.Da By("Getting GlobalNetworkPolicy (name2) and expecting an error") _, outError = c.GlobalNetworkPolicies().Get(ctx, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: GlobalNetworkPolicy(" + tieredGNPName(name2, tier) + ") with error:")) }, - // Pass two fully populated GlobalNetworkPolicySpecs and expect the series of operations to succeed. - Entry("Two fully populated GlobalNetworkPolicySpecs", name1, name2, spec1, spec2, ingressEgress, ingressEgress), + // Pass two fully populated GlobalNetworkPolicySpecs in default tier and expect the series of operations to succeed. + Entry("Two fully populated GlobalNetworkPolicySpecs", "default", name1, name2, spec1, spec2, ingressEgress, ingressEgress), // Check defaulting for policies with ingress rules and egress rules only. - Entry("Ingress-only and egress-only policies", name1, name2, ingressSpec1, egressSpec2, ingress, egress), + Entry("Ingress-only and egress-only policies", "default", name1, name2, ingressSpec1, egressSpec2, ingress, egress), // Check non-defaulting for policies with explicit Types value. - Entry("Policies with explicit ingress and egress Types", name1, name2, ingressTypesSpec1, egressTypesSpec2, ingress, egress), + Entry("Policies with explicit ingress and egress Types", "default", name1, name2, ingressTypesSpec1, egressTypesSpec2, ingress, egress), + // Pass two fully populated GlobalNetworkPolicySpecs in a tier, and expect the series of operations to succeed. + Entry("Two fully populated GlobalNetworkPolicySpecs", tier, tier+"."+name1, tier+"."+name2, spec1, spec2, ingressEgress, ingressEgress), ) Describe("GlobalNetworkPolicy watch functionality", func() { It("should handle watch events for different resource versions and event types", func() { - c, err := clientv3.New(config) - Expect(err).NotTo(HaveOccurred()) - - be, err := backend.NewClient(config) - Expect(err).NotTo(HaveOccurred()) - be.Clean() - By("Listing GlobalNetworkPolicies with the latest resource version and checking for two results with name1/spec2 and name2/spec2") outList, outError := c.GlobalNetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) diff --git a/libcalico-go/lib/clientv3/interface.go b/libcalico-go/lib/clientv3/interface.go index 85376e15b79..dc577eee392 100644 --- a/libcalico-go/lib/clientv3/interface.go +++ b/libcalico-go/lib/clientv3/interface.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -41,6 +41,8 @@ type Interface interface { CalicoNodeStatusClient IPAMConfigClient BlockAffinitiesClient + // Tiers returns an interface for managing tier resources. + Tiers() TierInterface // EnsureInitialized is used to ensure the backend datastore is correctly // initialized for use by Calico. This method may be called multiple times, and diff --git a/libcalico-go/lib/clientv3/networkpolicy.go b/libcalico-go/lib/clientv3/networkpolicy.go index 11233f1d13c..75716812b71 100644 --- a/libcalico-go/lib/clientv3/networkpolicy.go +++ b/libcalico-go/lib/clientv3/networkpolicy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,11 +17,15 @@ package clientv3 import ( "context" + "github.com/projectcalico/calico/libcalico-go/lib/names" + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" "github.com/projectcalico/calico/libcalico-go/lib/options" validator "github.com/projectcalico/calico/libcalico-go/lib/validator/v3" "github.com/projectcalico/calico/libcalico-go/lib/watch" + + log "github.com/sirupsen/logrus" ) // NetworkPolicyInterface has methods to work with NetworkPolicy resources. @@ -42,6 +46,13 @@ type networkPolicies struct { // Create takes the representation of a NetworkPolicy and creates it. Returns the stored // representation of the NetworkPolicy, and an error, if there is any. func (r networkPolicies) Create(ctx context.Context, res *apiv3.NetworkPolicy, opts options.SetOptions) (*apiv3.NetworkPolicy, error) { + // Before creating the policy, check that the tier exists. + tier := names.TierOrDefault(res.Spec.Tier) + if _, err := r.client.resources.Get(ctx, options.GetOptions{}, apiv3.KindTier, noNamespace, tier); err != nil { + log.WithError(err).Infof("Tier %v does not exist", tier) + return nil, err + } + if res != nil { // Since we're about to default some fields, take a (shallow) copy of the input data // before we do so. @@ -55,16 +66,27 @@ func (r networkPolicies) Create(ctx context.Context, res *apiv3.NetworkPolicy, o } // Properly prefix the name - res.GetObjectMeta().SetName(convertPolicyNameForStorage(res.GetObjectMeta().GetName())) + backendPolicyName, err := names.BackendTieredPolicyName(res.GetObjectMeta().GetName(), res.Spec.Tier) + if err != nil { + return nil, err + } + res.GetObjectMeta().SetName(backendPolicyName) + + // Add tier labels to policy for lookup. + if tier != "default" { + res.GetObjectMeta().SetLabels(addTierLabel(res.GetObjectMeta().GetLabels(), tier)) + } + out, err := r.client.resources.Create(ctx, opts, apiv3.KindNetworkPolicy, res) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) return out.(*apiv3.NetworkPolicy), err } - // Remove the prefix out of the returned policy name. - res.GetObjectMeta().SetName(convertPolicyNameFromStorage(res.GetObjectMeta().GetName())) + // Add the tier labels if necessary + res.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(res.GetObjectMeta().GetLabels())) + return nil, err } @@ -84,25 +106,38 @@ func (r networkPolicies) Update(ctx context.Context, res *apiv3.NetworkPolicy, o } // Properly prefix the name - res.GetObjectMeta().SetName(convertPolicyNameForStorage(res.GetObjectMeta().GetName())) + backendPolicyName, err := names.BackendTieredPolicyName(res.GetObjectMeta().GetName(), res.Spec.Tier) + if err != nil { + return nil, err + } + res.GetObjectMeta().SetName(backendPolicyName) + + // Add tier labels to policy for lookup. + tier := names.TierOrDefault(res.Spec.Tier) + if tier != "default" { + res.GetObjectMeta().SetLabels(addTierLabel(res.GetObjectMeta().GetLabels(), tier)) + } + out, err := r.client.resources.Update(ctx, opts, apiv3.KindNetworkPolicy, res) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) return out.(*apiv3.NetworkPolicy), err } - // Remove the prefix out of the returned policy name. - res.GetObjectMeta().SetName(convertPolicyNameFromStorage(res.GetObjectMeta().GetName())) + // Add the tier labels if necessary + res.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(res.GetObjectMeta().GetLabels())) + return nil, err } // Delete takes name of the NetworkPolicy and deletes it. Returns an error if one occurs. func (r networkPolicies) Delete(ctx context.Context, namespace, name string, opts options.DeleteOptions) (*apiv3.NetworkPolicy, error) { - out, err := r.client.resources.Delete(ctx, opts, apiv3.KindNetworkPolicy, namespace, convertPolicyNameForStorage(name)) + backendPolicyName := names.TieredPolicyName(name) + out, err := r.client.resources.Delete(ctx, opts, apiv3.KindNetworkPolicy, namespace, backendPolicyName) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) return out.(*apiv3.NetworkPolicy), err } return nil, err @@ -111,11 +146,23 @@ func (r networkPolicies) Delete(ctx context.Context, namespace, name string, opt // Get takes name of the NetworkPolicy, and returns the corresponding NetworkPolicy object, // and an error if there is any. func (r networkPolicies) Get(ctx context.Context, namespace, name string, opts options.GetOptions) (*apiv3.NetworkPolicy, error) { - out, err := r.client.resources.Get(ctx, opts, apiv3.KindNetworkPolicy, namespace, convertPolicyNameForStorage(name)) + backendPolicyName := names.TieredPolicyName(name) + out, err := r.client.resources.Get(ctx, opts, apiv3.KindNetworkPolicy, namespace, backendPolicyName) if out != nil { - // Remove the prefix out of the returned policy name. - out.GetObjectMeta().SetName(convertPolicyNameFromStorage(out.GetObjectMeta().GetName())) - return out.(*apiv3.NetworkPolicy), err + // Add the tier labels if necessary + out.GetObjectMeta().SetLabels(defaultTierLabelIfMissing(out.GetObjectMeta().GetLabels())) + // Fill in the tier information from the policy name if we find it missing. + // We expect backend policies to have the right name (prefixed with tier name). + res_out := out.(*apiv3.NetworkPolicy) + if res_out.Spec.Tier == "" { + tier, tierErr := names.TierFromPolicyName(res_out.Name) + if tierErr != nil { + log.WithError(tierErr).Infof("Skipping setting tier for name %v", res_out.Name) + return res_out, tierErr + } + res_out.Spec.Tier = tier + } + return res_out, err } return nil, err } @@ -124,18 +171,27 @@ func (r networkPolicies) Get(ctx context.Context, namespace, name string, opts o func (r networkPolicies) List(ctx context.Context, opts options.ListOptions) (*apiv3.NetworkPolicyList, error) { res := &apiv3.NetworkPolicyList{} // Add the name prefix if name is provided - if opts.Name != "" { - opts.Name = convertPolicyNameForStorage(opts.Name) + if opts.Name != "" && !opts.Prefix { + opts.Name = names.TieredPolicyName(opts.Name) } if err := r.client.resources.List(ctx, opts, apiv3.KindNetworkPolicy, apiv3.KindNetworkPolicyList, res); err != nil { return nil, err } - // Remove the prefix off of each policy name + // Make sure the tier labels are added for i, _ := range res.Items { - name := res.Items[i].GetObjectMeta().GetName() - res.Items[i].GetObjectMeta().SetName(convertPolicyNameFromStorage(name)) + res.Items[i].GetObjectMeta().SetLabels(defaultTierLabelIfMissing(res.Items[i].GetObjectMeta().GetLabels())) + // Fill in the tier information from the policy name if we find it missing. + // We expect backend policies to have the right name (prefixed with tier name). + if res.Items[i].Spec.Tier == "" { + tier, tierErr := names.TierFromPolicyName(res.Items[i].Name) + if tierErr != nil { + log.WithError(tierErr).Infof("Skipping setting tier for name %v", res.Items[i].Name) + continue + } + res.Items[i].Spec.Tier = tier + } } return res, nil @@ -146,7 +202,7 @@ func (r networkPolicies) List(ctx context.Context, opts options.ListOptions) (*a func (r networkPolicies) Watch(ctx context.Context, opts options.ListOptions) (watch.Interface, error) { // Add the name prefix if name is provided if opts.Name != "" { - opts.Name = convertPolicyNameForStorage(opts.Name) + opts.Name = names.TieredPolicyName(opts.Name) } return r.client.resources.Watch(ctx, opts, apiv3.KindNetworkPolicy, &policyConverter{}) diff --git a/libcalico-go/lib/clientv3/networkpolicy_e2e_test.go b/libcalico-go/lib/clientv3/networkpolicy_e2e_test.go index f1e0bb4817b..8a798305d77 100644 --- a/libcalico-go/lib/clientv3/networkpolicy_e2e_test.go +++ b/libcalico-go/lib/clientv3/networkpolicy_e2e_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,12 +29,23 @@ import ( "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" "github.com/projectcalico/calico/libcalico-go/lib/backend" + bapi "github.com/projectcalico/calico/libcalico-go/lib/backend/api" "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/names" "github.com/projectcalico/calico/libcalico-go/lib/options" "github.com/projectcalico/calico/libcalico-go/lib/testutils" "github.com/projectcalico/calico/libcalico-go/lib/watch" ) +func tieredNetworkPolicyName(ns, p, t string) string { + name, _ := names.BackendTieredPolicyName(p, t) + return ns + "/" + name +} + +func tieredPolicyName(p, t string) string { + return tieredGNPName(p, t) +} + // UID to use in tests, since our code expects valid UIDs. const uid = "41cb1fde-57e7-42c1-a73b-0acaf38c7737" @@ -46,6 +57,9 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor namespace2 := "namespace-2" name1 := "networkp-1" name2 := "networkp-2" + tier := "tier-a" + tierOrder := float64(10) + actionPass := apiv3.Pass spec1 := apiv3.NetworkPolicySpec{ Order: &order1, Ingress: []apiv3.Rule{testutils.InRule1, testutils.InRule2}, @@ -69,14 +83,38 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor egressTypesSpec2 := spec2 egressTypesSpec2.Types = egress - DescribeTable("NetworkPolicy e2e CRUD tests", - func(namespace1, namespace2, name1, name2 string, spec1, spec2 apiv3.NetworkPolicySpec, types1, types2 []apiv3.PolicyType) { - c, err := clientv3.New(config) - Expect(err).NotTo(HaveOccurred()) + var c clientv3.Interface + var be bapi.Client - be, err := backend.NewClient(config) - Expect(err).NotTo(HaveOccurred()) - be.Clean() + BeforeEach(func() { + var err error + c, err = clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) + + be, err = backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + err = c.EnsureInitialized(ctx, "", "") + Expect(err).NotTo(HaveOccurred()) + }) + + DescribeTable("NetworkPolicy e2e CRUD tests", + func(tier, namespace1, namespace2, name1, name2 string, spec1, spec2 apiv3.NetworkPolicySpec, types1, types2 []apiv3.PolicyType) { + spec1.Tier = tier + spec2.Tier = tier + + if tier != "" && tier != "default" { + // Create the tier if required before running other tiered policy tests. + tierSpec := apiv3.TierSpec{Order: &tierOrder, DefaultAction: &actionPass} + By("Creating the tier") + tierRes, resErr := c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: tier}, + Spec: tierSpec, + }, options.SetOptions{}) + Expect(resErr).NotTo(HaveOccurred()) + Expect(tierRes).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, tier, tierSpec)) + } By("Updating the NetworkPolicy before it is created") rv := "1234" @@ -85,7 +123,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor Spec: spec1, }, options.SetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + namespace1 + "/default." + name1 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + tieredNetworkPolicyName(namespace1, name1, tier) + ") with error:")) By("Attempting to creating a new NetworkPolicy with name1/spec1 and a non-empty ResourceVersion") _, outError = c.NetworkPolicies().Create(ctx, &apiv3.NetworkPolicy{ @@ -102,7 +140,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor }, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) spec1.Types = types1 - Expect(res1).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, name1, spec1)) + Expect(res1).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec1)) // Track the version of the original data for name1. rv1_1 := res1.ResourceVersion @@ -113,24 +151,24 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor Spec: spec2, }, options.SetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(Equal("resource already exists: NetworkPolicy(" + namespace1 + "/default." + name1 + ")")) + Expect(outError.Error()).To(Equal("resource already exists: NetworkPolicy(" + tieredNetworkPolicyName(namespace1, name1, tier) + ")")) By("Getting NetworkPolicy (name1) and comparing the output against spec1") res, outError := c.NetworkPolicies().Get(ctx, namespace1, name1, options.GetOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, name1, spec1)) + Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec1)) Expect(res.ResourceVersion).To(Equal(res1.ResourceVersion)) By("Getting NetworkPolicy (name2) before it is created") _, outError = c.NetworkPolicies().Get(ctx, namespace2, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + namespace2 + "/default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + tieredNetworkPolicyName(namespace2, name2, tier) + ") with error:")) By("Listing all the NetworkPolicies in namespace1, expecting a single result with name1/spec1") outList, outError := c.NetworkPolicies().List(ctx, options.ListOptions{Namespace: namespace1}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindNetworkPolicy, namespace1, name1, spec1), + testutils.Resource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec1), )) By("Creating a new NetworkPolicy with name2/spec2") @@ -140,34 +178,34 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor }, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) spec2.Types = types2 - Expect(res2).To(MatchResource(apiv3.KindNetworkPolicy, namespace2, name2, spec2)) + Expect(res2).To(MatchResource(apiv3.KindNetworkPolicy, namespace2, tieredPolicyName(name2, tier), spec2)) By("Getting NetworkPolicy (name2) and comparing the output against spec2") res, outError = c.NetworkPolicies().Get(ctx, namespace2, name2, options.GetOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace2, name2, spec2)) + Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace2, tieredPolicyName(name2, tier), spec2)) Expect(res.ResourceVersion).To(Equal(res2.ResourceVersion)) By("Listing all the NetworkPolicies using an empty namespace (all-namespaces), expecting a two results with name1/spec1 and name2/spec2") outList, outError = c.NetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindNetworkPolicy, namespace1, name1, spec1), - testutils.Resource(apiv3.KindNetworkPolicy, namespace2, name2, spec2), + testutils.Resource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec1), + testutils.Resource(apiv3.KindNetworkPolicy, namespace2, tieredPolicyName(name2, tier), spec2), )) By("Listing all the NetworkPolicies in namespace2, expecting a one results with name2/spec2") outList, outError = c.NetworkPolicies().List(ctx, options.ListOptions{Namespace: namespace2}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindNetworkPolicy, namespace2, name2, spec2), + testutils.Resource(apiv3.KindNetworkPolicy, namespace2, tieredPolicyName(name2, tier), spec2), )) By("Updating NetworkPolicy name1 with spec2") res1.Spec = spec2 res1, outError = c.NetworkPolicies().Update(ctx, res1, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(res1).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, name1, spec2)) + Expect(res1).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec2)) By("Attempting to update the NetworkPolicy without a Creation Timestamp") res, outError = c.NetworkPolicies().Update(ctx, &apiv3.NetworkPolicy{ @@ -202,20 +240,20 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor res1.ResourceVersion = rv1_1 _, outError = c.NetworkPolicies().Update(ctx, res1, options.SetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(Equal("update conflict: NetworkPolicy(" + namespace1 + "/default." + name1 + ")")) + Expect(outError.Error()).To(Equal("update conflict: NetworkPolicy(" + tieredNetworkPolicyName(namespace1, name1, tier) + ")")) if config.Spec.DatastoreType != apiconfig.Kubernetes { By("Getting NetworkPolicy (name1) with the original resource version and comparing the output against spec1") res, outError = c.NetworkPolicies().Get(ctx, namespace1, name1, options.GetOptions{ResourceVersion: rv1_1}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, name1, spec1)) + Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec1)) Expect(res.ResourceVersion).To(Equal(rv1_1)) } By("Getting NetworkPolicy (name1) with the updated resource version and comparing the output against spec2") res, outError = c.NetworkPolicies().Get(ctx, namespace1, name1, options.GetOptions{ResourceVersion: rv1_2}) Expect(outError).NotTo(HaveOccurred()) - Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, name1, spec2)) + Expect(res).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec2)) Expect(res.ResourceVersion).To(Equal(rv1_2)) if config.Spec.DatastoreType != apiconfig.Kubernetes { @@ -223,7 +261,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor outList, outError = c.NetworkPolicies().List(ctx, options.ListOptions{Namespace: namespace1, ResourceVersion: rv1_1}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindNetworkPolicy, namespace1, name1, spec1), + testutils.Resource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec1), )) } @@ -231,21 +269,21 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor outList, outError = c.NetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) Expect(outList.Items).To(ConsistOf( - testutils.Resource(apiv3.KindNetworkPolicy, namespace1, name1, spec2), - testutils.Resource(apiv3.KindNetworkPolicy, namespace2, name2, spec2), + testutils.Resource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec2), + testutils.Resource(apiv3.KindNetworkPolicy, namespace2, tieredPolicyName(name2, tier), spec2), )) if config.Spec.DatastoreType != apiconfig.Kubernetes { By("Deleting NetworkPolicy (name1) with the old resource version") _, outError = c.NetworkPolicies().Delete(ctx, namespace1, name1, options.DeleteOptions{ResourceVersion: rv1_1}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(Equal("update conflict: NetworkPolicy(" + namespace1 + "/default." + name1 + ")")) + Expect(outError.Error()).To(Equal("update conflict: NetworkPolicy(" + tieredNetworkPolicyName(namespace1, name1, tier) + ")")) } By("Deleting NetworkPolicy (name1) with the new resource version") dres, outError := c.NetworkPolicies().Delete(ctx, namespace1, name1, options.DeleteOptions{ResourceVersion: rv1_2}) Expect(outError).NotTo(HaveOccurred()) - Expect(dres).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, name1, spec2)) + Expect(dres).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, tieredPolicyName(name1, tier), spec2)) if config.Spec.DatastoreType != apiconfig.Kubernetes { By("Updating NetworkPolicy name2 with a 2s TTL and waiting for the entry to be deleted") @@ -257,7 +295,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor time.Sleep(2 * time.Second) _, outError = c.NetworkPolicies().Get(ctx, namespace2, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + namespace2 + "/default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + tieredNetworkPolicyName(namespace2, name2, tier) + ") with error:")) By("Creating NetworkPolicy name2 with a 2s TTL and waiting for the entry to be deleted") _, outError = c.NetworkPolicies().Create(ctx, &apiv3.NetworkPolicy{ @@ -271,20 +309,20 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor time.Sleep(2 * time.Second) _, outError = c.NetworkPolicies().Get(ctx, namespace2, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + namespace2 + "/default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + tieredNetworkPolicyName(namespace2, name2, tier) + ") with error:")) } if config.Spec.DatastoreType == apiconfig.Kubernetes { By("Attempting to deleting NetworkPolicy (name2) again") dres, outError = c.NetworkPolicies().Delete(ctx, namespace2, name2, options.DeleteOptions{}) Expect(outError).NotTo(HaveOccurred()) - Expect(dres).To(MatchResource(apiv3.KindNetworkPolicy, namespace2, name2, spec2)) + Expect(dres).To(MatchResource(apiv3.KindNetworkPolicy, namespace2, tieredPolicyName(name2, tier), spec2)) } By("Attempting to delete NetworkPolicy (name2) again") _, outError = c.NetworkPolicies().Delete(ctx, namespace2, name2, options.DeleteOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + namespace2 + "/default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + tieredNetworkPolicyName(namespace2, name2, tier) + ") with error:")) By("Listing all NetworkPolicies and expecting no items") outList, outError = c.NetworkPolicies().List(ctx, options.ListOptions{}) @@ -294,11 +332,12 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor By("Getting NetworkPolicy (name2) and expecting an error") _, outError = c.NetworkPolicies().Get(ctx, namespace2, name2, options.GetOptions{}) Expect(outError).To(HaveOccurred()) - Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + namespace2 + "/default." + name2 + ") with error:")) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: NetworkPolicy(" + tieredNetworkPolicyName(namespace2, name2, tier) + ") with error:")) }, // Pass two fully populated PolicySpecs and expect the series of operations to succeed. - Entry("Two fully populated PolicySpecs", + Entry("Two fully populated PolicySpecs in the default tier", + "default", namespace1, namespace2, name1, name2, spec1, spec2, @@ -306,6 +345,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor ), // Check defaulting for policies with ingress rules and egress rules only. Entry("Ingress-only and egress-only policies", + "default", namespace1, namespace2, name1, name2, ingressSpec1, egressSpec2, @@ -313,22 +353,23 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor ), // Check non-defaulting for policies with explicit Types value. Entry("Policies with explicit ingress and egress Types", + "default", namespace1, namespace2, name1, name2, ingressTypesSpec1, egressTypesSpec2, ingress, egress, ), + Entry("Two fully populated PolicySpecs in tier", + tier, + namespace1, namespace2, + tier+"."+name1, tier+"."+name2, + spec1, spec2, + ingressEgress, ingressEgress, + ), ) Describe("NetworkPolicy watch functionality", func() { It("should handle watch events for different resource versions and event types", func() { - c, err := clientv3.New(config) - Expect(err).NotTo(HaveOccurred()) - - be, err := backend.NewClient(config) - Expect(err).NotTo(HaveOccurred()) - be.Clean() - By("Listing NetworkPolicies with the latest resource version and checking for two results with name1/spec2 and name2/spec2") outList, outError := c.NetworkPolicies().List(ctx, options.ListOptions{}) Expect(outError).NotTo(HaveOccurred()) @@ -344,6 +385,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor }, options.SetOptions{}, ) + Expect(err).NotTo(HaveOccurred()) rev1 := outRes1.ResourceVersion By("Configuring a NetworkPolicy namespace2/name2/spec2 and storing the response") @@ -385,6 +427,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor testWatcher2 := testutils.NewTestResourceWatch(config.Spec.DatastoreType, w) defer testWatcher2.Stop() + // Revert back to client input By("Modifying res2") outRes3, err := c.NetworkPolicies().Update( ctx, @@ -491,9 +534,9 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor // prefix. nameNormalizationTests := []TableEntry{ // OpenStack names should round-trip, including their prefix. - Entry("OpenStack policy", "ossg.default.group1", "ossg.default.group1"), + Entry("OpenStack policy", "ossg.default.group1", "ossg.default.group1", "default"), // As should normal names. - Entry("OpenStack policy", "foo-bar", "default.foo-bar"), + Entry("OpenStack policy", "default.foo-bar", "default.foo-bar", "default"), } if config.Spec.DatastoreType != "kubernetes" { // Only test writing a knp-prefixed policy if we're not backed by KDD. In KDD, @@ -501,22 +544,32 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor // to write them through our API. knpName := "knp.default.a-name" nameNormalizationTests = append(nameNormalizationTests, - Entry("KDD policy", knpName, knpName), + Entry("KDD policy", knpName, knpName, "default"), ) } - DescribeTable("name round-tripping tests", - func(name, backendName string) { - c, err := clientv3.New(config) - Expect(err).NotTo(HaveOccurred()) + BeforeEach(func() { + var err error + c, err = clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) - be, err := backend.NewClient(config) - Expect(err).NotTo(HaveOccurred()) - be.Clean() + be, err = backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + err = c.EnsureInitialized(ctx, "", "") + Expect(err).NotTo(HaveOccurred()) + }) + DescribeTable("name round-tripping tests", + func(name, backendName, tierName string) { + tieredIngressTypesSpec1 := ingressTypesSpec1 + tieredIngressTypesSpec1.Tier = tierName + tieredEgressTypesSpec2 := egressTypesSpec2 + tieredEgressTypesSpec2.Tier = tierName By("Attempting to creating a new NetworkPolicy with name: " + name) inNp := &apiv3.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{Namespace: namespace1, Name: name}, - Spec: ingressTypesSpec1, + Spec: tieredIngressTypesSpec1, } np, outError := c.NetworkPolicies().Create(ctx, inNp, options.SetOptions{}) Expect(outError).NotTo(HaveOccurred()) @@ -533,16 +586,16 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor Name: backendName, }, "") Expect(err).NotTo(HaveOccurred()) - Expect(kv.Value.(*apiv3.NetworkPolicy).Spec).To(Equal(ingressTypesSpec1)) + Expect(kv.Value.(*apiv3.NetworkPolicy).Spec).To(Equal(tieredIngressTypesSpec1)) By("Getting the right policy by name") np, err = c.NetworkPolicies().Get(ctx, namespace1, name, options.GetOptions{}) Expect(err).NotTo(HaveOccurred()) Expect(np.GetName()).To(Equal(name)) - Expect(np.Spec).To(Equal(ingressTypesSpec1)) + Expect(np.Spec).To(Equal(tieredIngressTypesSpec1)) By("Updating the policy") - np.Spec = egressTypesSpec2 + np.Spec = tieredEgressTypesSpec2 np, err = c.NetworkPolicies().Update(ctx, np, options.SetOptions{}) Expect(err).NotTo(HaveOccurred()) @@ -550,7 +603,7 @@ var _ = testutils.E2eDatastoreDescribe("NetworkPolicy tests", testutils.Datastor np, err = c.NetworkPolicies().Get(ctx, namespace1, name, options.GetOptions{}) Expect(err).NotTo(HaveOccurred()) Expect(np.GetName()).To(Equal(name)) - Expect(np.Spec).To(Equal(egressTypesSpec2)) + Expect(np.Spec).To(Equal(tieredEgressTypesSpec2)) By("Listing the policy with correct name (no query options)") nps, err := c.NetworkPolicies().List(ctx, options.ListOptions{Namespace: namespace1}) diff --git a/libcalico-go/lib/clientv3/node_e2e_test.go b/libcalico-go/lib/clientv3/node_e2e_test.go index 0fb5bfcfeed..e9b7a5ba60b 100644 --- a/libcalico-go/lib/clientv3/node_e2e_test.go +++ b/libcalico-go/lib/clientv3/node_e2e_test.go @@ -289,7 +289,7 @@ var _ = testutils.E2eDatastoreDescribe("Node tests (etcdv3)", testutils.Datastor handle := "myhandle" err = c.IPAM().AssignIP(ctx, ipam.AssignIPArgs{ - IP: cnet.IP{wepIp}, + IP: cnet.IP{IP: wepIp}, Hostname: name1, HandleID: &handle, }) diff --git a/libcalico-go/lib/clientv3/tier.go b/libcalico-go/lib/clientv3/tier.go new file mode 100644 index 00000000000..0945945d80d --- /dev/null +++ b/libcalico-go/lib/clientv3/tier.go @@ -0,0 +1,173 @@ +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package clientv3 + +import ( + "context" + "fmt" + + log "github.com/sirupsen/logrus" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" + "github.com/projectcalico/calico/libcalico-go/lib/options" + cresources "github.com/projectcalico/calico/libcalico-go/lib/resources" + validator "github.com/projectcalico/calico/libcalico-go/lib/validator/v3" + "github.com/projectcalico/calico/libcalico-go/lib/watch" +) + +// TierInterface has methods to work with Tier resources. +type TierInterface interface { + Create(ctx context.Context, res *apiv3.Tier, opts options.SetOptions) (*apiv3.Tier, error) + Update(ctx context.Context, res *apiv3.Tier, opts options.SetOptions) (*apiv3.Tier, error) + Delete(ctx context.Context, name string, opts options.DeleteOptions) (*apiv3.Tier, error) + Get(ctx context.Context, name string, opts options.GetOptions) (*apiv3.Tier, error) + List(ctx context.Context, opts options.ListOptions) (*apiv3.TierList, error) + Watch(ctx context.Context, opts options.ListOptions) (watch.Interface, error) +} + +// tiers implements TierInterface +type tiers struct { + client client +} + +// Create takes the representation of a Tier and creates it. Returns the stored +// representation of the Tier, and an error, if there is any. +func (r tiers) Create(ctx context.Context, res *apiv3.Tier, opts options.SetOptions) (*apiv3.Tier, error) { + if res != nil { + // Since we're about to default some fields, take a (shallow) copy of the input data + // before we do so. + resCopy := *res + res = &resCopy + } + cresources.DefaultTierFields(res) + if err := validator.Validate(res); err != nil { + return nil, err + } + out, err := r.client.resources.Create(ctx, opts, apiv3.KindTier, res) + if out != nil { + return out.(*apiv3.Tier), err + } + return nil, err +} + +// Update takes the representation of a Tier and updates it. Returns the stored +// representation of the Tier, and an error, if there is any. +func (r tiers) Update(ctx context.Context, res *apiv3.Tier, opts options.SetOptions) (*apiv3.Tier, error) { + if res != nil { + // Since we're about to default some fields, take a (shallow) copy of the input data + // before we do so. + resCopy := *res + res = &resCopy + } + cresources.DefaultTierFields(res) + if err := validator.Validate(res); err != nil { + return nil, err + } + out, err := r.client.resources.Update(ctx, opts, apiv3.KindTier, res) + if out != nil { + return out.(*apiv3.Tier), err + } + return nil, err +} + +// Delete takes name of the Tier and deletes it. Returns an error if one occurs. +func (r tiers) Delete(ctx context.Context, name string, opts options.DeleteOptions) (*apiv3.Tier, error) { + if name == names.DefaultTierName || name == names.AdminNetworkPolicyTierName { + return nil, cerrors.ErrorOperationNotSupported{ + Identifier: name, + Operation: "Delete", + Reason: fmt.Sprintf("Cannot delete %v tier", name), + } + } + + // List the NetworkPolicy and GlobalNetworkPolicy resources that are prefixed with this tier name. Note that + // a prefix matching may return additional results that are not actually in this tier, so we also need to check + // the spec field to be certain. + policyListOptions := options.ListOptions{ + Prefix: true, + Name: name + ".", + } + + // Check NetworkPolicy resources. + if npList, err := r.client.NetworkPolicies().List(ctx, policyListOptions); err != nil { + return nil, err + } else { + for _, np := range npList.Items { + if np.Spec.Tier == name { + log.WithField("name", np.Name).Debug("Enumerated NetworkPolicy is in this tier") + return nil, cerrors.ErrorOperationNotSupported{ + Operation: "delete", + Identifier: name, + Reason: "Cannot delete a non-empty tier", + } + } + } + } + + // Check GlobalNetworkPolicy resources. + if gnpList, err := r.client.GlobalNetworkPolicies().List(ctx, policyListOptions); err != nil { + return nil, err + } else { + for _, gnp := range gnpList.Items { + if gnp.Spec.Tier == name { + log.WithField("name", gnp.Name).Debug("Enumerated GlobalNetworkPolicy is in this tier") + return nil, cerrors.ErrorOperationNotSupported{ + Operation: "delete", + Identifier: name, + Reason: "Cannot delete a non-empty tier", + } + } + } + } + + out, err := r.client.resources.Delete(ctx, opts, apiv3.KindTier, noNamespace, name) + if out != nil { + return out.(*apiv3.Tier), err + } + return nil, err +} + +// Get takes name of the Tier, and returns the corresponding Tier object, +// and an error if there is any. +func (r tiers) Get(ctx context.Context, name string, opts options.GetOptions) (*apiv3.Tier, error) { + out, err := r.client.resources.Get(ctx, opts, apiv3.KindTier, noNamespace, name) + if out != nil { + res := out.(*apiv3.Tier) + return res, err + } + return nil, err +} + +// List returns the list of Tier objects that match the supplied options. +func (r tiers) List(ctx context.Context, opts options.ListOptions) (*apiv3.TierList, error) { + res := &apiv3.TierList{} + if err := r.client.resources.List(ctx, opts, apiv3.KindTier, apiv3.KindTierList, res); err != nil { + return nil, err + } + // Default values when reading from backend. + for i := range res.Items { + cresources.DefaultTierFields(&res.Items[i]) + } + return res, nil +} + +// Watch returns a watch.Interface that watches the tiers that match the +// supplied options. +func (r tiers) Watch(ctx context.Context, opts options.ListOptions) (watch.Interface, error) { + return r.client.resources.Watch(ctx, opts, apiv3.KindTier, nil) +} diff --git a/libcalico-go/lib/clientv3/tier_e2e_test.go b/libcalico-go/lib/clientv3/tier_e2e_test.go new file mode 100644 index 00000000000..ffdbe5e8157 --- /dev/null +++ b/libcalico-go/lib/clientv3/tier_e2e_test.go @@ -0,0 +1,837 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package clientv3_test + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" + "github.com/projectcalico/calico/libcalico-go/lib/backend" + "github.com/projectcalico/calico/libcalico-go/lib/clientv3" + "github.com/projectcalico/calico/libcalico-go/lib/names" + "github.com/projectcalico/calico/libcalico-go/lib/options" + "github.com/projectcalico/calico/libcalico-go/lib/testutils" + "github.com/projectcalico/calico/libcalico-go/lib/watch" +) + +var _ = testutils.E2eDatastoreDescribe("Tier tests", testutils.DatastoreAll, func(config apiconfig.CalicoAPIConfig) { + ctx := context.Background() + defaultOrder := apiv3.DefaultTierOrder + order1 := 99.999 + order2 := 22.222 + actionDeny := apiv3.Deny + actionPass := apiv3.Pass + name1 := "t-1" + name2 := "t-12" + defaultName := "default" + namespace1 := "namespace-1" + spec1 := apiv3.TierSpec{ + Order: &order1, + DefaultAction: &actionDeny, + } + spec2 := apiv3.TierSpec{} + spec2UpdatedOrder := apiv3.TierSpec{ + Order: &defaultOrder, + DefaultAction: &actionDeny, + } + defaultSpec := apiv3.TierSpec{ + Order: &defaultOrder, + DefaultAction: &actionDeny, + } + anpOrder := apiv3.AdminNetworkPolicyTierOrder + anpSpec := apiv3.TierSpec{ + Order: &anpOrder, + DefaultAction: &actionPass, + } + + npName1 := name1 + ".networkp-1" + npSpec1 := apiv3.NetworkPolicySpec{ + Tier: name1, + Order: &order1, + Ingress: []apiv3.Rule{testutils.InRule1, testutils.InRule2}, + Egress: []apiv3.Rule{testutils.EgressRule1, testutils.EgressRule2}, + Selector: "thing == 'value'", + } + + gnpName1 := name1 + ".globalnetworkp-1" + gnpSpec1 := apiv3.GlobalNetworkPolicySpec{ + Tier: name1, + Order: &order2, + Ingress: []apiv3.Rule{testutils.InRule2, testutils.InRule1}, + Egress: []apiv3.Rule{testutils.EgressRule2, testutils.EgressRule1}, + Selector: "thing2 == 'value2'", + DoNotTrack: true, + ApplyOnForward: true, + } + + gnpName2 := name2 + ".globalnetworkp-1" + gnpSpec2 := apiv3.GlobalNetworkPolicySpec{ + Tier: name2, + Order: &order2, + Ingress: []apiv3.Rule{testutils.InRule2, testutils.InRule1}, + Egress: []apiv3.Rule{testutils.EgressRule2, testutils.EgressRule1}, + Selector: "thing2 == 'value2'", + DoNotTrack: true, + ApplyOnForward: true, + } + + DescribeTable("Tier e2e CRUD tests", + func(name1, name2, npName1, gnpName1, gnpName2, namespace1 string, spec1, spec2 apiv3.TierSpec, npSpec1 apiv3.NetworkPolicySpec, gnpSpec1, gnpSpec2 apiv3.GlobalNetworkPolicySpec) { + c, err := clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) + + be, err := backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + err = c.EnsureInitialized(ctx, "", "") + Expect(err).NotTo(HaveOccurred()) + + By("Creating a tier with nil order should result in a tier with the default order") + res, outError := c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "app-tier"}, + Spec: apiv3.TierSpec{DefaultAction: &actionPass}, + }, options.SetOptions{}) + defaultOrder := apiv3.DefaultTierOrder + Expect(outError).NotTo(HaveOccurred()) + Expect(res.Name).To(Equal("app-tier")) + Expect(res.Spec.DefaultAction).To(Equal(&actionPass)) + Expect(res.Spec.Order).To(Equal(&defaultOrder)) + _, outError = c.Tiers().Delete(ctx, "app-tier", options.DeleteOptions{}) + Expect(outError).NotTo(HaveOccurred()) + + By("Updating a tier order to nil should result in the default order") + order := float64(10.0) + res, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "app-tier"}, + Spec: apiv3.TierSpec{ + Order: &order, + DefaultAction: &actionDeny, + }, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res.Name).To(Equal("app-tier")) + Expect(res.Spec.DefaultAction).To(Equal(&actionDeny)) + Expect(res.Spec.Order).To(Equal(&order)) + res, outError = c.Tiers().Update(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{ + Name: "app-tier", + ResourceVersion: res.ResourceVersion, + CreationTimestamp: res.CreationTimestamp, + UID: res.UID, + }, + Spec: apiv3.TierSpec{DefaultAction: &actionPass}, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res.Name).To(Equal("app-tier")) + Expect(res.Spec.DefaultAction).To(Equal(&actionPass)) + Expect(res.Spec.Order).To(Equal(&defaultOrder)) + _, outError = c.Tiers().Delete(ctx, "app-tier", options.DeleteOptions{}) + Expect(outError).NotTo(HaveOccurred()) + + By("Creating the default tier with an invalid order") + res, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: defaultName}, + Spec: spec1, + }, options.SetOptions{}) + Expect(res).To(BeNil()) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).Should(ContainSubstring("default tier order must be 1e+06")) + + By("Cannot delete the default Tier") + _, outError = c.Tiers().Delete(ctx, defaultName, options.DeleteOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("operation Delete is not supported on default: Cannot delete default tier")) + + By("Getting default Tier") + defRes, outError := c.Tiers().Get(ctx, defaultName, options.GetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(defRes).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, defaultName, defaultSpec)) + + By("Cannot update the default Tier") + defRes.Spec = spec1 + _, outError = c.Tiers().Update(ctx, defRes, options.SetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).Should(ContainSubstring("default tier order must be 1e+06")) + + By("Creating the adminnetworkpolicy tier with an invalid order") + res, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: names.AdminNetworkPolicyTierName}, + Spec: spec1, + }, options.SetOptions{}) + Expect(res).To(BeNil()) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).Should(ContainSubstring("adminnetworkpolicy tier order must be 1000")) + + By("Cannot delete the adminnetworkpolicy Tier") + _, outError = c.Tiers().Delete(ctx, names.AdminNetworkPolicyTierName, options.DeleteOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("operation Delete is not supported on adminnetworkpolicy: Cannot delete adminnetworkpolicy tier")) + + By("Getting adminnetworkpolicy Tier") + defRes, outError = c.Tiers().Get(ctx, names.AdminNetworkPolicyTierName, options.GetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(defRes).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, names.AdminNetworkPolicyTierName, anpSpec)) + + By("Cannot update the adminnetworkpolicy Tier") + defRes.Spec = spec1 + _, outError = c.Tiers().Update(ctx, defRes, options.SetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).Should(ContainSubstring("adminnetworkpolicy tier order must be 1000")) + + By("Updating the Tier before it is created") + res, outError = c.Tiers().Update(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name1, ResourceVersion: "1234", CreationTimestamp: metav1.Now(), UID: uid}, + Spec: spec1, + }, options.SetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(res).To(BeNil()) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: Tier(" + name1 + ") with error:")) + + By("Attempting to create a new Tier with too long of a name") + longName := "thisisareallylongnamethatislongerthansixtythreecharactersthatwillnotfitinalabel" + res, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: longName}, + Spec: spec1, + }, options.SetOptions{}) + Expect(res).To(BeNil()) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("error with field Metadata.Name = 'thisisareallylongnamethatislongerthansixtythreecharactersthatwillnotfitinalabel' (name is too long by 16 bytes)")) + + By("Attempting to create a new Tier with name1/spec1 and a non-empty ResourceVersion") + res, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name1, ResourceVersion: "12345"}, + Spec: spec1, + }, options.SetOptions{}) + Expect(res).To(BeNil()) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("error with field Metadata.ResourceVersion = '12345' (field must not be set for a Create request)")) + + By("Creating a new Tier with name1/spec1") + res1, outError := c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name1}, + Spec: spec1, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res1).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec1)) + + // Track the version of the original data for name1. + rv1_1 := res1.ResourceVersion + + By("Attempting to create the same Tier with name1 but with spec2") + _, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name1}, + Spec: spec2, + }, options.SetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("resource already exists: Tier(" + name1 + ")")) + + By("Getting Tier (name1) and comparing the output against spec1") + res, outError = c.Tiers().Get(ctx, name1, options.GetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec1)) + Expect(res.ResourceVersion).To(Equal(res1.ResourceVersion)) + + By("Getting Tier (name2) before it is created") + _, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: Tier(" + name2 + ") with error:")) + + By("Listing all the Tiers, expecting a single result with name1/spec1") + outList, outError := c.Tiers().List(ctx, options.ListOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(outList.Items).To(HaveLen(3)) + Expect(&outList.Items[0]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, names.AdminNetworkPolicyTierName, anpSpec)) + Expect(&outList.Items[1]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, defaultName, defaultSpec)) + Expect(&outList.Items[2]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec1)) + + By("Creating a new Tier with name2/spec2") + res2, outError := c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name2}, + Spec: spec2, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res2).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name2, spec2UpdatedOrder)) + + By("Getting Tier (name2) and comparing the output against spec2") + res, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res2).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name2, spec2UpdatedOrder)) + Expect(res.ResourceVersion).To(Equal(res2.ResourceVersion)) + + By("Listing all the Tiers, expecting a two results with name1/spec1 and name2/spec2") + outList, outError = c.Tiers().List(ctx, options.ListOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(outList.Items).To(HaveLen(4)) + Expect(&outList.Items[0]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, names.AdminNetworkPolicyTierName, anpSpec)) + Expect(&outList.Items[1]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, defaultName, defaultSpec)) + Expect(&outList.Items[2]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec1)) + Expect(&outList.Items[3]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name2, spec2UpdatedOrder)) + + By("Updating Tier name1 with spec2") + res1.Spec = spec2 + res1, outError = c.Tiers().Update(ctx, res1, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res1).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec2UpdatedOrder)) + + // Track the version of the updated name1 data. + rv1_2 := res1.ResourceVersion + + By("Updating Tier name1 without specifying a resource version") + res1.Spec = spec1 + res1.ObjectMeta.ResourceVersion = "" + _, outError = c.Tiers().Update(ctx, res1, options.SetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("error with field Metadata.ResourceVersion = '' (field must be set for an Update request)")) + + By("Updating Tier name1 using the previous resource version") + res1.Spec = spec1 + res1.ResourceVersion = rv1_1 + _, outError = c.Tiers().Update(ctx, res1, options.SetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("update conflict: Tier(" + name1 + ")")) + + if config.Spec.DatastoreType != apiconfig.Kubernetes { + By("Getting Tier (name1) with the original resource version and comparing the output against spec1") + res, outError = c.Tiers().Get(ctx, name1, options.GetOptions{ResourceVersion: rv1_1}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec1)) + Expect(res.ResourceVersion).To(Equal(rv1_1)) + } + + By("Getting Tier (name1) with the updated resource version and comparing the output against spec2") + res, outError = c.Tiers().Get(ctx, name1, options.GetOptions{ResourceVersion: rv1_2}) + Expect(outError).NotTo(HaveOccurred()) + Expect(res).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec2UpdatedOrder)) + Expect(res.ResourceVersion).To(Equal(rv1_2)) + + if config.Spec.DatastoreType != apiconfig.Kubernetes { + By("Listing Tiers with the original resource version and checking for a single result with name1/spec1") + outList, outError = c.Tiers().List(ctx, options.ListOptions{ResourceVersion: rv1_1}) + Expect(outError).NotTo(HaveOccurred()) + Expect(outList.Items).To(HaveLen(3)) + Expect(&outList.Items[2]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec1)) + } + + By("Listing Tiers with the latest resource version and checking for two results with name1/spec2 and name2/spec2") + outList, outError = c.Tiers().List(ctx, options.ListOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(outList.Items).To(HaveLen(4)) + Expect(&outList.Items[0]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, names.AdminNetworkPolicyTierName, anpSpec)) + Expect(&outList.Items[1]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, defaultName, defaultSpec)) + Expect(&outList.Items[2]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec2UpdatedOrder)) + Expect(&outList.Items[3]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name2, spec2UpdatedOrder)) + + if config.Spec.DatastoreType != apiconfig.Kubernetes { + By("Deleting Tier (name1) with the old resource version") + _, outError = c.Tiers().Delete(ctx, name1, options.DeleteOptions{ResourceVersion: rv1_1}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(Equal("update conflict: Tier(" + name1 + ")")) + } + + By("Attempting to delete Tier (name1) when there is a NetworkPolicy in it") + np1, outError := c.NetworkPolicies().Create(ctx, &apiv3.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: npName1, Namespace: namespace1}, + Spec: npSpec1, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + npSpec1.Types = []apiv3.PolicyType{apiv3.PolicyTypeIngress, apiv3.PolicyTypeEgress} + Expect(np1).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, npName1, npSpec1)) + rv_np := np1.ResourceVersion + + dres, outError := c.Tiers().Delete(ctx, name1, options.DeleteOptions{ResourceVersion: rv1_2}) + Expect(outError).To(HaveOccurred()) + + dnp, outError := c.NetworkPolicies().Delete(ctx, namespace1, npName1, options.DeleteOptions{ResourceVersion: rv_np}) + Expect(outError).NotTo(HaveOccurred()) + Expect(dnp).To(MatchResource(apiv3.KindNetworkPolicy, namespace1, npName1, npSpec1)) + + By("Attempting to delete Tier (name1) when there is a GlobalNetworkPolicy in it") + gnp1, outError := c.GlobalNetworkPolicies().Create(ctx, &apiv3.GlobalNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: gnpName1}, + Spec: gnpSpec1, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + gnpSpec1.Types = []apiv3.PolicyType{apiv3.PolicyTypeIngress, apiv3.PolicyTypeEgress} + Expect(gnp1).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, gnpName1, gnpSpec1)) + rv_gnp := gnp1.ResourceVersion + + dres, outError = c.Tiers().Delete(ctx, name1, options.DeleteOptions{ResourceVersion: rv1_2}) + Expect(outError).To(HaveOccurred()) + + dgnp, outError := c.GlobalNetworkPolicies().Delete(ctx, gnpName1, options.DeleteOptions{ResourceVersion: rv_gnp}) + Expect(outError).NotTo(HaveOccurred()) + Expect(dgnp).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, gnpName1, gnpSpec1)) + time.Sleep(1 * time.Second) + + By("Deleting Tier (name1) with the new resource version") + // Make sure that policies on other tiers are not associated with other tiers + gnp2, outError := c.GlobalNetworkPolicies().Create(ctx, &apiv3.GlobalNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: gnpName2}, + Spec: gnpSpec2, + }, options.SetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + gnpSpec2.Types = []apiv3.PolicyType{apiv3.PolicyTypeIngress, apiv3.PolicyTypeEgress} + Expect(gnp2).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, gnpName2, gnpSpec2)) + rv_gnp2 := gnp2.ResourceVersion + + dres, outError = c.Tiers().Delete(ctx, name1, options.DeleteOptions{ResourceVersion: rv1_2}) + Expect(outError).NotTo(HaveOccurred()) + Expect(dres).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name1, spec2UpdatedOrder)) + + // Delete policy on the other tier + dgnp, outError = c.GlobalNetworkPolicies().Delete(ctx, gnpName2, options.DeleteOptions{ResourceVersion: rv_gnp2}) + Expect(outError).NotTo(HaveOccurred()) + Expect(dgnp).To(MatchResource(apiv3.KindGlobalNetworkPolicy, testutils.ExpectNoNamespace, gnpName2, gnpSpec2)) + time.Sleep(1 * time.Second) + + if config.Spec.DatastoreType != apiconfig.Kubernetes { + By("Updating Tier name2 with a 2s TTL and waiting for the entry to be deleted") + _, outError = c.Tiers().Update(ctx, res2, options.SetOptions{TTL: 2 * time.Second}) + Expect(outError).NotTo(HaveOccurred()) + time.Sleep(1 * time.Second) + _, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + time.Sleep(2 * time.Second) + _, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: Tier(" + name2 + ") with error:")) + + By("Creating Tier name2 with a 2s TTL and waiting for the entry to be deleted") + _, outError = c.Tiers().Create(ctx, &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name2}, + Spec: spec2, + }, options.SetOptions{TTL: 2 * time.Second}) + Expect(outError).NotTo(HaveOccurred()) + time.Sleep(1 * time.Second) + _, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).NotTo(HaveOccurred()) + time.Sleep(2 * time.Second) + _, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: Tier(" + name2 + ") with error:")) + } + + if config.Spec.DatastoreType == apiconfig.Kubernetes { + By("Deleting Tier (name2)") + dres, outError = c.Tiers().Delete(ctx, name2, options.DeleteOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(dres).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, name2, spec2UpdatedOrder)) + } + + By("Attempting to deleting Tier (name2) again") + _, outError = c.Tiers().Delete(ctx, name2, options.DeleteOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: Tier(" + name2 + ") with error:")) + + By("Listing all Tiers and expecting only the default and adminnetworkpolicy tiers") + outList, outError = c.Tiers().List(ctx, options.ListOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(outList.Items).To(HaveLen(2)) + Expect(&outList.Items[0]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, names.AdminNetworkPolicyTierName, anpSpec)) + Expect(&outList.Items[1]).To(MatchResource(apiv3.KindTier, testutils.ExpectNoNamespace, defaultName, defaultSpec)) + + By("Getting Tier (name2) and expecting an error") + res, outError = c.Tiers().Get(ctx, name2, options.GetOptions{}) + Expect(outError).To(HaveOccurred()) + Expect(outError.Error()).To(ContainSubstring("resource does not exist: Tier(" + name2 + ") with error:")) + }, + + // Test 1: Pass two fully populated TierSpecs and expect the series of operations to succeed. + Entry("Two fully populated TierSpecs", name1, name2, npName1, gnpName1, gnpName2, namespace1, spec1, spec2, npSpec1, gnpSpec1, gnpSpec2), + ) + + Describe("Tier watch functionality", func() { + It("should handle watch events for different resource versions and event types", func() { + c, err := clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) + + be, err := backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + By("Listing Tiers with the latest resource version and checking for two results with name1/spec2 and name2/spec2") + outList, outError := c.Tiers().List(ctx, options.ListOptions{}) + Expect(outError).NotTo(HaveOccurred()) + Expect(outList.Items).To(HaveLen(0)) + rev0 := outList.ResourceVersion + + By("Configuring a Tier name1/spec1 and storing the response") + outRes1, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name1}, + Spec: spec1, + }, + options.SetOptions{}, + ) + rev1 := outRes1.ResourceVersion + + By("Configuring a Tier name2/spec2 and storing the response") + outRes2, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name2}, + Spec: spec2, + }, + options.SetOptions{}, + ) + + By("Starting a watcher from revision rev1 - this should skip the first creation") + w, err := c.Tiers().Watch(ctx, options.ListOptions{ResourceVersion: rev1}) + Expect(err).NotTo(HaveOccurred()) + testWatcher1 := testutils.NewTestResourceWatch(config.Spec.DatastoreType, w) + defer testWatcher1.Stop() + + By("Deleting res1") + _, err = c.Tiers().Delete(ctx, name1, options.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + time.Sleep(1 * time.Second) + + By("Checking for two events, create res2 and delete re1") + testWatcher1.ExpectEvents(apiv3.KindTier, []watch.Event{ + { + Type: watch.Added, + Object: outRes2, + }, + { + Type: watch.Deleted, + Previous: outRes1, + }, + }) + testWatcher1.Stop() + + By("Starting a watcher from rev0 - this should get all events") + w, err = c.Tiers().Watch(ctx, options.ListOptions{ResourceVersion: rev0}) + Expect(err).NotTo(HaveOccurred()) + testWatcher2 := testutils.NewTestResourceWatch(config.Spec.DatastoreType, w) + defer testWatcher2.Stop() + + By("Modifying res2") + outRes3, err := c.Tiers().Update( + ctx, + &apiv3.Tier{ + ObjectMeta: outRes2.ObjectMeta, + Spec: spec1, + }, + options.SetOptions{}, + ) + Expect(err).NotTo(HaveOccurred()) + testWatcher2.ExpectEvents(apiv3.KindTier, []watch.Event{ + { + Type: watch.Added, + Object: outRes1, + }, + { + Type: watch.Added, + Object: outRes2, + }, + { + Type: watch.Deleted, + Previous: outRes1, + }, + { + Type: watch.Modified, + Previous: outRes2, + Object: outRes3, + }, + }) + testWatcher2.Stop() + + // Only etcdv3 supports watching a specific instance of a resource. + if config.Spec.DatastoreType == apiconfig.EtcdV3 { + By("Starting a watcher from rev0 watching name1 - this should get all events for name1") + w, err = c.Tiers().Watch(ctx, options.ListOptions{Name: name1, ResourceVersion: rev0}) + Expect(err).NotTo(HaveOccurred()) + testWatcher2_1 := testutils.NewTestResourceWatch(config.Spec.DatastoreType, w) + defer testWatcher2_1.Stop() + testWatcher2_1.ExpectEvents(apiv3.KindTier, []watch.Event{ + { + Type: watch.Added, + Object: outRes1, + }, + { + Type: watch.Deleted, + Previous: outRes1, + }, + }) + testWatcher2_1.Stop() + } + + By("Starting a watcher not specifying a rev - expect the current snapshot") + w, err = c.Tiers().Watch(ctx, options.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + testWatcher3 := testutils.NewTestResourceWatch(config.Spec.DatastoreType, w) + defer testWatcher3.Stop() + testWatcher3.ExpectEvents(apiv3.KindTier, []watch.Event{ + { + Type: watch.Added, + Object: outRes3, + }, + }) + testWatcher3.Stop() + + By("Configuring Tier name1/spec1 again and storing the response") + outRes1, err = c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: name1}, + Spec: spec1, + }, + options.SetOptions{}, + ) + + By("Starting a watcher not specifying a rev - expect the current snapshot") + w, err = c.Tiers().Watch(ctx, options.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + testWatcher4 := testutils.NewTestResourceWatch(config.Spec.DatastoreType, w) + defer testWatcher4.Stop() + testWatcher4.ExpectEventsAnyOrder(apiv3.KindTier, []watch.Event{ + { + Type: watch.Added, + Object: outRes1, + }, + { + Type: watch.Added, + Object: outRes3, + }, + }) + + By("Cleaning the datastore and expecting deletion events for each configured resource (tests prefix deletes results in individual events for each key)") + be.Clean() + testWatcher4.ExpectEvents(apiv3.KindTier, []watch.Event{ + { + Type: watch.Deleted, + Previous: outRes1, + }, + { + Type: watch.Deleted, + Previous: outRes3, + }, + }) + testWatcher4.Stop() + }) + }) + + Describe("Tier delete functionality", func() { + var c clientv3.Interface + var err error + + BeforeEach(func() { + c, err = clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) + + be, err := backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + // These tests use the default tier, so make sure it's created. + err = c.EnsureInitialized(ctx, "", "") + Expect(err).NotTo(HaveOccurred()) + }) + + It("cannot delete tier `tier-1` if there is a GlobalNetworkPolicy configured in it", func() { + By("Configuring a Tier called tier-1") + tier, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "tier-1"}, + Spec: spec1, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Configuring a GlobalNetworkPolicy in tier-1") + gnp, err := c.GlobalNetworkPolicies().Create( + ctx, + &apiv3.GlobalNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "tier-1.gnp1"}, + Spec: apiv3.GlobalNetworkPolicySpec{ + Tier: "tier-1", + Order: &order2, + Ingress: []apiv3.Rule{}, + Egress: []apiv3.Rule{}, + Selector: "thing2 == 'value2'", + }, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting failure)") + _, err = c.Tiers().Delete(ctx, "tier-1", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).To(HaveOccurred()) + + By("Deleting the GNP") + _, err = c.GlobalNetworkPolicies().Delete( + ctx, "tier-1.gnp1", options.DeleteOptions{ResourceVersion: gnp.ResourceVersion}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting success)") + _, err = c.Tiers().Delete(ctx, "tier-1", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).NotTo(HaveOccurred()) + }) + + It("cannot delete tier `tier-1` if there is a NetworkPolicy configured in it", func() { + By("Configuring a Tier called tier-1") + tier, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "tier-1"}, + Spec: spec1, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Configuring a NetworkPolicy in tier-1") + np, err := c.NetworkPolicies().Create( + ctx, + &apiv3.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "tier-1.np1", Namespace: "namespace-1"}, + Spec: apiv3.NetworkPolicySpec{ + Tier: "tier-1", + Order: &order2, + Ingress: []apiv3.Rule{}, + Egress: []apiv3.Rule{}, + Selector: "thing2 == 'value2'", + }, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting failure)") + _, err = c.Tiers().Delete(ctx, "tier-1", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).To(HaveOccurred()) + + By("Deleting the NP") + _, err = c.NetworkPolicies().Delete( + ctx, "namespace-1", "tier-1.np1", options.DeleteOptions{ResourceVersion: np.ResourceVersion}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting success)") + _, err = c.Tiers().Delete(ctx, "tier-1", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).NotTo(HaveOccurred()) + }) + + if config.Spec.DatastoreType != apiconfig.Kubernetes { + // The issue with knp tier not being deletable was due to the prefix based enumeration of policies in etcdv3. + // For kubernetes, we use label matching instead - and so it isn't an issue. We skip this test for kubernetes + // because it isn'tt possible to create pretend "k8s" policies through the Calico API. + It("can delete tier `knp` if there is a k8s-backed NetworkPolicy configured", func() { + By("Configuring a Tier called knp") + tier, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "knp"}, + Spec: spec1, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Configuring a k8s-backed NetworkPolicy called knp.default.test") + np, err := c.NetworkPolicies().Create( + ctx, + &apiv3.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "knp.default.np", Namespace: "namespace-1"}, + Spec: apiv3.NetworkPolicySpec{ + Tier: "default", + Order: &order2, + Ingress: []apiv3.Rule{}, + Egress: []apiv3.Rule{}, + Selector: "thing2 == 'value2'", + }, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting success)") + _, err = c.Tiers().Delete(ctx, "knp", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).ToNot(HaveOccurred()) + + By("Deleting the NP") + _, err = c.NetworkPolicies().Delete( + ctx, "namespace-1", "knp.default.np", options.DeleteOptions{ResourceVersion: np.ResourceVersion}, + ) + Expect(err).ToNot(HaveOccurred()) + }) + } + + It("cannot delete tier `knp` if there is a NetworkPolicy configured in it", func() { + c, err := clientv3.New(config) + Expect(err).NotTo(HaveOccurred()) + + be, err := backend.NewClient(config) + Expect(err).NotTo(HaveOccurred()) + be.Clean() + + By("Configuring a Tier called knp") + tier, err := c.Tiers().Create( + ctx, + &apiv3.Tier{ + ObjectMeta: metav1.ObjectMeta{Name: "knp"}, + Spec: spec1, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Configuring a NetworkPolicy called knp.default.test") + np, err := c.NetworkPolicies().Create( + ctx, + &apiv3.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{Name: "knp.np1", Namespace: "namespace-1"}, + Spec: apiv3.NetworkPolicySpec{ + Tier: "knp", + Order: &order2, + Ingress: []apiv3.Rule{}, + Egress: []apiv3.Rule{}, + Selector: "thing2 == 'value2'", + }, + }, + options.SetOptions{}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting failure)") + _, err = c.Tiers().Delete(ctx, "knp", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).To(HaveOccurred()) + + By("Deleting the NP") + _, err = c.NetworkPolicies().Delete( + ctx, "namespace-1", "knp.np1", options.DeleteOptions{ResourceVersion: np.ResourceVersion}, + ) + Expect(err).ToNot(HaveOccurred()) + + By("Attempting to delete tier-1 (expecting success)") + _, err = c.Tiers().Delete(ctx, "knp", options.DeleteOptions{ResourceVersion: tier.ResourceVersion}) + Expect(err).ToNot(HaveOccurred()) + }) + }) +}) diff --git a/libcalico-go/lib/converter/policy.go b/libcalico-go/lib/converter/policy.go index ba0d2efa3bf..c252c683e4e 100644 --- a/libcalico-go/lib/converter/policy.go +++ b/libcalico-go/lib/converter/policy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import ( api "github.com/projectcalico/calico/libcalico-go/lib/apis/v1" "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" "github.com/projectcalico/calico/libcalico-go/lib/backend/model" + "github.com/projectcalico/calico/libcalico-go/lib/names" ) // PolicyConverter implements a set of functions used for converting between @@ -29,6 +30,7 @@ func (p PolicyConverter) ConvertMetadataToKey(m unversioned.ResourceMetadata) (m pm := m.(api.PolicyMetadata) k := model.PolicyKey{ Name: pm.Name, + Tier: names.TierOrDefault(pm.Tier), } return k, nil } @@ -99,6 +101,7 @@ func (p PolicyConverter) ConvertKVPairToAPI(d *model.KVPair) (unversioned.Resour ap := api.NewPolicy() ap.Metadata.Name = bk.Name + ap.Metadata.Tier = bk.Tier ap.Metadata.Annotations = bp.Annotations ap.Spec.Order = bp.Order ap.Spec.IngressRules = RulesBackendToAPI(bp.InboundRules) diff --git a/libcalico-go/lib/errors/errors.go b/libcalico-go/lib/errors/errors.go index 5cfecf9d7d7..27c1b304fd3 100644 --- a/libcalico-go/lib/errors/errors.go +++ b/libcalico-go/lib/errors/errors.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + adminpolicy "sigs.k8s.io/network-policy-api/apis/v1alpha1" ) // Error indicating a problem connecting to the backend. @@ -43,7 +44,7 @@ func (e ErrorDatastoreError) Status() metav1.Status { Status: metav1.StatusFailure, Code: http.StatusBadRequest, Reason: metav1.StatusReasonInvalid, - Message: fmt.Sprintf(e.Error()), + Message: e.Error(), Details: &metav1.StatusDetails{ Name: fmt.Sprintf("%v", e.Identifier), }, @@ -228,13 +229,68 @@ func (e ErrorParsingDatastoreEntry) Error() string { return fmt.Sprintf("failed to parse datastore entry key=%s; value=%s: %v", e.RawKey, e.RawValue, e.Err) } -type ErrorPolicyConversionRule struct { - EgressRule *networkingv1.NetworkPolicyEgressRule - IngressRule *networkingv1.NetworkPolicyIngressRule +type ErrorAdminPolicyConversion struct { + PolicyName string + Rules []ErrorAdminPolicyConversionRule +} + +func (e *ErrorAdminPolicyConversion) BadEgressRule(rule *adminpolicy.AdminNetworkPolicyEgressRule, reason string) { + // Copy rule + badRule := *rule + + e.Rules = append(e.Rules, ErrorAdminPolicyConversionRule{ + EgressRule: &badRule, + IngressRule: nil, + Reason: reason, + }) +} + +func (e *ErrorAdminPolicyConversion) BadIngressRule(rule *adminpolicy.AdminNetworkPolicyIngressRule, reason string) { + // Copy rule + badRule := *rule + + e.Rules = append(e.Rules, ErrorAdminPolicyConversionRule{ + EgressRule: nil, + IngressRule: &badRule, + Reason: reason, + }) +} + +func (e ErrorAdminPolicyConversion) Error() string { + s := fmt.Sprintf("policy: %s", e.PolicyName) + + switch { + case len(e.Rules) == 0: + s += ": unknown policy conversion error" + case len(e.Rules) == 1: + f := e.Rules[0] + + s += fmt.Sprintf(": error with rule %s", f) + default: + s += ": error with the following rules:\n" + for _, f := range e.Rules { + s += fmt.Sprintf("- %s\n", f) + } + } + + return s +} + +func (e ErrorAdminPolicyConversion) GetError() error { + if len(e.Rules) == 0 { + return nil + } + + return e +} + +type ErrorAdminPolicyConversionRule struct { + EgressRule *adminpolicy.AdminNetworkPolicyEgressRule + IngressRule *adminpolicy.AdminNetworkPolicyIngressRule Reason string } -func (e ErrorPolicyConversionRule) String() string { +func (e ErrorAdminPolicyConversionRule) String() string { var fieldString string switch { @@ -258,6 +314,31 @@ type ErrorPolicyConversion struct { Rules []ErrorPolicyConversionRule } +type ErrorPolicyConversionRule struct { + EgressRule *networkingv1.NetworkPolicyEgressRule + IngressRule *networkingv1.NetworkPolicyIngressRule + Reason string +} + +func (e ErrorPolicyConversionRule) String() string { + var fieldString string + + switch { + case e.EgressRule != nil: + fieldString = fmt.Sprintf("%+v", e.EgressRule) + case e.IngressRule != nil: + fieldString = fmt.Sprintf("%+v", e.IngressRule) + default: + fieldString = "unknown rule" + } + + if e.Reason != "" { + fieldString = fmt.Sprintf("%s (%s)", fieldString, e.Reason) + } + + return fieldString +} + func (e *ErrorPolicyConversion) BadEgressRule(rule *networkingv1.NetworkPolicyEgressRule, reason string) { // Copy rule badRule := *rule diff --git a/libcalico-go/lib/ipam/ipam.go b/libcalico-go/lib/ipam/ipam.go index c08cbbda8a3..a72e02486f6 100644 --- a/libcalico-go/lib/ipam/ipam.go +++ b/libcalico-go/lib/ipam/ipam.go @@ -588,7 +588,7 @@ func (s *blockAssignState) findOrClaimBlock(ctx context.Context, minFreeIps int) } else { errString := fmt.Sprintf("Block '%s' has %d free ips which is less than %d ips required.", b.Key.(model.BlockKey).CIDR, numFree, minFreeIps) - logCtx.Errorf(errString) + logCtx.Errorf("%s", errString) return nil, false, errors.New(errString) } } diff --git a/libcalico-go/lib/ipam/ipam_block_reader_writer_test.go b/libcalico-go/lib/ipam/ipam_block_reader_writer_test.go index 0c9cfa12d13..e8e9fb8802d 100644 --- a/libcalico-go/lib/ipam/ipam_block_reader_writer_test.go +++ b/libcalico-go/lib/ipam/ipam_block_reader_writer_test.go @@ -68,7 +68,6 @@ func (c *fakeClient) Create(ctx context.Context, object *model.KVPair) (*model.K } panic(fmt.Sprintf("Create called on unexpected object: %+v", object)) - return nil, nil } func (c *fakeClient) Update(ctx context.Context, object *model.KVPair) (*model.KVPair, error) { if f, ok := c.updateFuncs[object.Key.String()]; ok { @@ -77,12 +76,10 @@ func (c *fakeClient) Update(ctx context.Context, object *model.KVPair) (*model.K return f(ctx, object) } panic(fmt.Sprintf("Update called on unexpected object: %+v", object)) - return nil, nil } func (c *fakeClient) Apply(ctx context.Context, object *model.KVPair) (*model.KVPair, error) { panic("should not be called") - return nil, nil } func (c *fakeClient) DeleteKVP(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) { @@ -93,7 +90,6 @@ func (c *fakeClient) DeleteKVP(ctx context.Context, kvp *model.KVPair) (*model.K } panic(fmt.Sprintf("DeleteKVP called on unexpected object: %+v", kvp.Key)) - return nil, nil } func (c *fakeClient) Delete(ctx context.Context, key model.Key, revision string) (*model.KVPair, error) { @@ -104,7 +100,6 @@ func (c *fakeClient) Delete(ctx context.Context, key model.Key, revision string) } panic(fmt.Sprintf("Delete called on unexpected object: %+v", key)) - return nil, nil } func (c *fakeClient) Get(ctx context.Context, key model.Key, revision string) (*model.KVPair, error) { @@ -114,22 +109,18 @@ func (c *fakeClient) Get(ctx context.Context, key model.Key, revision string) (* return f(ctx, key, revision) } panic(fmt.Sprintf("Get called on unexpected object: %+v", key)) - return nil, nil } func (c *fakeClient) Syncer(callbacks api.SyncerCallbacks) api.Syncer { panic("should not be called") - return nil } func (c *fakeClient) EnsureInitialized() error { panic("should not be called") - return nil } func (c *fakeClient) Clean() error { panic("should not be called") - return nil } func (c *fakeClient) List(ctx context.Context, list model.ListInterface, revision string) (*model.KVPairList, error) { @@ -139,12 +130,10 @@ func (c *fakeClient) List(ctx context.Context, list model.ListInterface, revisio return f(ctx, list, revision) } panic(fmt.Sprintf("List called on unexpected object: %+v", list)) - return nil, nil } func (c *fakeClient) Watch(ctx context.Context, list model.ListInterface, revision string) (api.WatchInterface, error) { panic("should not be called") - return nil, nil } // backendClientAccessor is an interface used to access the backend client from the main clientv3. @@ -392,7 +381,7 @@ var _ = testutils.E2eDatastoreDescribe("IPAM affine block allocation tests", tes if len(failed) != 0 || len(success) != 16 { s := fmt.Sprintf("%s failed to claim affinity for %v, succeeded on %v", testhost, failed, success) log.WithError(err).Error(s) - testErr = fmt.Errorf(s) + testErr = fmt.Errorf("%s", s) } }() } diff --git a/libcalico-go/lib/logutils/benchmarks_test.go b/libcalico-go/lib/logutils/benchmarks_test.go index 3ff044b009f..097c99c9904 100644 --- a/libcalico-go/lib/logutils/benchmarks_test.go +++ b/libcalico-go/lib/logutils/benchmarks_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Tigera, Inc. All rights reserved. +// Copyright (c) 2019-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,62 +15,82 @@ package logutils import ( - "runtime" "testing" "github.com/sirupsen/logrus" ) -var result bool +func BenchmarkLogWithOurFormat(b *testing.B) { + logger := logrus.New() + logger.SetFormatter(&Formatter{}) + logger.SetReportCaller(true) + logger.SetOutput(&NullWriter{}) -func BenchmarkShouldSkipFrame(b *testing.B) { - var r bool - for n := 0; n < b.N; n++ { - r = shouldSkipFrame(runtime.Frame{File: "/home/ubuntu/go/src/github.com/projectcalico/libcalico-go/lib/foo/bar.go"}) + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + logger.Info("Test log") } - result = r } -// These functions are here to make sure we have plenty of stack frames to load when we call runtime.Callers() +func BenchmarkLogWithOurFormatFixedFields(b *testing.B) { + logger := logrus.New() + logger.SetFormatter(&Formatter{}) + logger.SetReportCaller(true) + logger.SetOutput(&NullWriter{}) -func benchmarkCallers5(b *testing.B) { - benchmarkCallers4(b) -} + b.ResetTimer() + b.ReportAllocs() -func benchmarkCallers4(b *testing.B) { - benchmarkCallers3(b) -} - -func benchmarkCallers3(b *testing.B) { - benchmarkCallers2(b) -} + entry := logger.WithFields(logrus.Fields{ + "a": "b", + "c": "d", + "e": "f", + "g": "h", + }) -func benchmarkCallers2(b *testing.B) { - benchmarkCallers1(b) + for i := 0; i < b.N; i++ { + entry.Info("Test log") + } } -func benchmarkCallers1(b *testing.B) { - benchmarkCallers(b) -} +func BenchmarkLogWithFieldOurFormat(b *testing.B) { + logger := logrus.New() + logger.SetFormatter(&Formatter{}) + logger.SetReportCaller(true) + logger.SetOutput(&NullWriter{}) -var pcsResult []uintptr -var skipResult int -var entry *logrus.Entry -var globalErr error + b.ResetTimer() + b.ReportAllocs() -func benchmarkCallers(b *testing.B) { - hook := &ContextHook{} - e := logrus.WithField("foo", "bar") - var err error + entry := logger.WithFields(logrus.Fields{ + "a": "b", + "c": "d", + "e": "f", + "g": "h", + }) - for n := 0; n < b.N; n++ { - err = hook.Fire(e) + for i := 0; i < b.N; i++ { + entry.WithField("f", "g").Info("Test log") } - - entry = e - globalErr = err } -func BenchmarkCallersSkip1(b *testing.B) { - benchmarkCallers5(b) +func BenchmarkLogWithFieldsOurFormat(b *testing.B) { + logger := logrus.New() + logger.SetFormatter(&Formatter{}) + logger.SetReportCaller(true) + logger.SetOutput(&NullWriter{}) + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + logger.WithFields(logrus.Fields{ + "a": "b", + "c": "d", + "e": "f", + "g": "h", + }).Info("Test log") + } } diff --git a/libcalico-go/lib/logutils/logutils.go b/libcalico-go/lib/logutils/logutils.go index 65becb10b03..d6f57af37e8 100644 --- a/libcalico-go/lib/logutils/logutils.go +++ b/libcalico-go/lib/logutils/logutils.go @@ -21,8 +21,8 @@ import ( "os" "path" "regexp" - "runtime" "sort" + "strconv" "strings" "sync" "testing" @@ -37,12 +37,16 @@ const ( // message. It can be used as follows: logrus.WithField(FieldForceFlush, true).Info("...") FieldForceFlush = "__flush__" - // fieldFileName is a reserved field name used to pass the filename from the ContextHook to our Formatter. - fieldFileName = "__file__" - // fieldLineNumber is a reserved field name used to pass the line number from the ContextHook to our Formatter. - fieldLineNumber = "__line__" + // FileNameUnknown is the string used in logs if the filename/line number + // cannot be determined. + FileNameUnknown = "" ) +func init() { + // We need logrus to record the caller on each log entry for us. + log.SetReportCaller(true) +} + // FilterLevels returns all the logrus.Level values <= maxLevel. func FilterLevels(maxLevel log.Level) []log.Level { levels := []log.Level{} @@ -54,6 +58,12 @@ func FilterLevels(maxLevel log.Level) []log.Level { return levels } +func ConfigureFormatter(componentName string) { + formatter := &Formatter{Component: componentName} + formatter.init() + log.SetFormatter(formatter) +} + // Formatter is our custom log formatter designed to balance ease of machine processing // with human readability. Logs include: // - A sortable millisecond timestamp, for scanning and correlating logs @@ -74,27 +84,109 @@ type Formatter struct { // multiple components are logging to the same file (e.g., calico/node) for distinguishing // which component sourced the log. Component string + + initOnce sync.Once + preComputedInfixByLevel []string +} + +var maxLevel = log.Level(len(log.AllLevels)) + +func (f *Formatter) init() { + f.initOnce.Do(func() { + f.preComputedInfixByLevel = make([]string, len(log.AllLevels)) + for _, level := range log.AllLevels { + var buf bytes.Buffer + f.computeInfix(&buf, level) + f.preComputedInfixByLevel[level] = buf.String() + } + }) } +const TimeFormat = "2006-01-02 15:04:05.000" +const timeFormatLen = len(TimeFormat) + func (f *Formatter) Format(entry *log.Entry) ([]byte, error) { - stamp := entry.Time.Format("2006-01-02 15:04:05.000") - levelStr := strings.ToUpper(entry.Level.String()) - pid := os.Getpid() - fileName := entry.Data[fieldFileName] - lineNo := entry.Data[fieldLineNumber] + f.init() + b := entry.Buffer if b == nil { b = &bytes.Buffer{} } - if f.Component != "" { - fmt.Fprintf(b, "%s [%s][%d] %s/%v %v: %v", stamp, levelStr, pid, f.Component, fileName, lineNo, entry.Message) + + fileName, lineNo := getFileInfo(entry) + + b.Grow(timeFormatLen + 32 + len(fileName) + len(entry.Message) + len(entry.Data)*32) + AppendTime(b, entry.Time) + f.writeInfix(b, entry.Level) + b.WriteString(fileName) + b.WriteByte(' ') + if lineNo == 0 { + b.WriteString(FileNameUnknown) } else { - fmt.Fprintf(b, "%s [%s][%d] %v %v: %v", stamp, levelStr, pid, fileName, lineNo, entry.Message) + buf := b.AvailableBuffer() + buf = strconv.AppendInt(buf, int64(lineNo), 10) + _, _ = b.Write(buf) } - appendKVsAndNewLine(b, entry) + b.WriteString(": ") + b.WriteString(entry.Message) + appendKVsAndNewLine(b, entry.Data) + return b.Bytes(), nil } +func (f *Formatter) writeInfix(b *bytes.Buffer, level log.Level) { + if level >= maxLevel { + // Slow path for unknown log levels. + f.computeInfix(b, level) + } + _, _ = b.WriteString(f.preComputedInfixByLevel[level]) +} + +func (f *Formatter) computeInfix(b *bytes.Buffer, level log.Level) { + _, _ = fmt.Fprintf(b, " [%s][%d] ", strings.ToUpper(level.String()), os.Getpid()) + if f.Component != "" { + _, _ = fmt.Fprintf(b, "%s/", f.Component) + } +} + +// AppendTime appends a time to the buffer in our format +// "2006-01-02 15:04:05.000". +func AppendTime(b *bytes.Buffer, t time.Time) { + // Want "2006-01-02 15:04:05.000" but the formatter has an optimised + // impl of RFC3339Nano, which we can easily tweak into our format. + b.Grow(timeFormatLen) + buf := b.AvailableBuffer() + buf = t.AppendFormat(buf, time.RFC3339Nano) + buf = buf[:timeFormatLen] + const tPos = len("2006-01-02T") - 1 + buf[tPos] = ' ' + const dotPos = len("2006-01-02T15:04:05.") - 1 + + // RFC3339Nano truncates the fractional seconds if zero, put the dot in + // place if it isn't already and overwrite any non-digit characters with + // zeros to replace the timezone or 'Z' that RFC3339Nano might have added. + overwrite := false + if buf[dotPos] != '.' { + buf[dotPos] = '.' + overwrite = true + } + for i := dotPos + 1; i < len(buf); i++ { + if overwrite || buf[i] < '0' || buf[i] > '9' { + buf[i] = '0' + overwrite = true + } + } + _, _ = b.Write(buf) +} + +var preComputedInfixByLevelSyslog = make([]string, len(log.AllLevels)) + +func init() { + for _, level := range log.AllLevels { + preComputedInfixByLevelSyslog[level] = strings.ToUpper(level.String()) + " " + } +} + // FormatForSyslog formats logs in a way tailored for syslog. It avoids logging information that is // already included in the syslog metadata such as timestamp and PID. The log level _is_ included // because syslog doesn't seem to output it by default and it's very useful. @@ -102,48 +194,91 @@ func (f *Formatter) Format(entry *log.Entry) ([]byte, error) { // INFO endpoint_mgr.go 434: Skipping configuration of interface because it is oper down. // ifaceName="cali1234" func FormatForSyslog(entry *log.Entry) string { - levelStr := strings.ToUpper(entry.Level.String()) - fileName := entry.Data[fieldFileName] - lineNo := entry.Data[fieldLineNumber] b := entry.Buffer if b == nil { b = &bytes.Buffer{} } - fmt.Fprintf(b, "%s %v %v: %v", levelStr, fileName, lineNo, entry.Message) - appendKVsAndNewLine(b, entry) + + fileName, lineNo := getFileInfo(entry) + + b.Grow(timeFormatLen + 32 + len(fileName) + len(entry.Message) + len(entry.Data)*32) + if entry.Level < maxLevel { + b.WriteString(preComputedInfixByLevelSyslog[entry.Level]) + } else { + b.WriteString(strings.ToUpper(entry.Level.String())) + b.WriteByte(' ') + } + b.WriteString(fileName) + b.WriteByte(' ') + if lineNo == 0 { + b.WriteString(FileNameUnknown) + } else { + buf := b.AvailableBuffer() + buf = strconv.AppendInt(buf, int64(lineNo), 10) + _, _ = b.Write(buf) + } + b.WriteString(": ") + b.WriteString(entry.Message) + appendKVsAndNewLine(b, entry.Data) + return b.String() } -// appendKeysAndNewLine writes the KV pairs attached to the entry to the end of the buffer, then -// finishes it with a newline. -func appendKVsAndNewLine(b *bytes.Buffer, entry *log.Entry) { +func getFileInfo(entry *log.Entry) (string, int) { + if entry.Caller == nil { + return FileNameUnknown, 0 + } + return path.Base(entry.Caller.File), entry.Caller.Line +} + +// appendKeysAndNewLine writes the entry's KV pairs to the end of the buffer, +// followed by a newline. Entries are written in sorted order. +func appendKVsAndNewLine(b *bytes.Buffer, data log.Fields) { + if len(data) == 0 { + b.WriteByte('\n') + return + } + // Sort the keys for consistent output. - var keys []string = make([]string, 0, len(entry.Data)) - for k := range entry.Data { + var keys []string + const arrSize = 16 + if len(data) < arrSize { + // Optimisation: avoid an allocation if the number of keys is small. + // make(...) always spills to the heap if the slice size is not known at + // compile time. + var dataArr [arrSize]string + keys = dataArr[:0] + } else { + keys = make([]string, 0, len(data)) + } + for k := range data { keys = append(keys, k) } sort.Strings(keys) for _, key := range keys { - if key == fieldFileName || key == fieldLineNumber || key == FieldForceFlush { - continue - } - var value interface{} = entry.Data[key] - var stringifiedValue string - if err, ok := value.(error); ok { - stringifiedValue = err.Error() - } else if stringer, ok := value.(fmt.Stringer); ok { - // Trust the value's String() method. - stringifiedValue = stringer.String() - } else { - // No string method, use %#v to get a more thorough dump. - fmt.Fprintf(b, " %v=%#v", key, value) + if key == FieldForceFlush { continue } + var value = data[key] b.WriteByte(' ') b.WriteString(key) b.WriteByte('=') - b.WriteString(stringifiedValue) + + switch value := value.(type) { + case string: + buf := b.AvailableBuffer() + buf = strconv.AppendQuote(buf, value) + b.Write(buf) + case error: + b.WriteString(value.Error()) + case fmt.Stringer: + // Trust the value's String() method. + b.WriteString(value.String()) + default: + // No string method, use %#v to get a more thorough dump. + _, _ = fmt.Fprintf(b, "%#v", value) + } } b.WriteByte('\n') } @@ -155,77 +290,6 @@ func (w *NullWriter) Write(p []byte) (int, error) { return len(p), nil } -type ContextHook struct { -} - -func (hook ContextHook) Levels() []log.Level { - return log.AllLevels -} - -func (hook ContextHook) Fire(entry *log.Entry) error { - // We used to do runtime.Callers(6, pcs) here so that we'd skip straight to the expected - // frame. However, if an intermediate frame gets inlined we can skip too many frames in - // that case. The only safe option is to use skip=1 and then let CallersFrames() deal - // with any inlining. - pcs := make([]uintptr, 20) - if numEntries := runtime.Callers(0, pcs); numEntries > 0 { - pcs = pcs[:numEntries] - frames := runtime.CallersFrames(pcs) - for { - frame, more := frames.Next() - if !shouldSkipFrame(frame) { - // We found the frame we were looking for. Record its file/line number. - entry.Data[fieldFileName] = path.Base(frame.File) - entry.Data[fieldLineNumber] = frame.Line - break - } - if !more { - entry.Data[fieldFileName] = "filename-lookup-failed" - entry.Data[fieldLineNumber] = -1 - break - } - } - } else { - entry.Data[fieldFileName] = "filename-lookup-failed" - entry.Data[fieldLineNumber] = -2 - } - return nil -} - -// shouldSkipFrame returns true if the given frame belongs to the logging library (or this utility package). -// Note: this is on the critical path for every log, if you need to update it, make sure to run the -// benchmarks. -// -// Some things we've tried that were worse than strings.HasSuffix(): -// -// - using a regexp: ~100x slower -// - using strings.LastIndex(): ~10x slower -// - omitting the package: no benefit -func shouldSkipFrame(frame runtime.Frame) bool { - if strings.Contains(frame.File, "runtime/extern.go") { - return true - } - if strings.HasSuffix(frame.File, "/hooks.go") || - strings.HasSuffix(frame.File, "/entry.go") || - strings.HasSuffix(frame.File, "/logger.go") || - strings.HasSuffix(frame.File, "/exported.go") { - if strings.Contains(frame.File, "/logrus") { - return true - } - } - if strings.HasSuffix(frame.File, "/lib/logutils/logutils.go") { - if strings.Contains(frame.File, "/libcalico-go") { - return true - } - } - if strings.HasSuffix(frame.File, "/lib/logutils/ratelimitedlogger.go") { - if strings.Contains(frame.File, "/libcalico-go") { - return true - } - } - return false -} - type QueuedLog struct { Level log.Level Message []byte @@ -255,7 +319,7 @@ func NewStreamDestination( Channel: c, writeLog: func(ql QueuedLog) error { if ql.NumSkippedLogs > 0 { - fmt.Fprintf(writer, "... dropped %d logs ...\n", + _, _ = fmt.Fprintf(writer, "... dropped %d logs ...\n", ql.NumSkippedLogs) } _, err := writer.Write(ql.Message) @@ -278,7 +342,7 @@ func NewSyslogDestination( Channel: c, writeLog: func(ql QueuedLog) error { if ql.NumSkippedLogs > 0 { - writer.Warning(fmt.Sprintf("... dropped %d logs ...\n", + _ = writer.Warning(fmt.Sprintf("... dropped %d logs ...\n", ql.NumSkippedLogs)) } err := writeToSyslog(writer, ql) @@ -341,7 +405,6 @@ func (d *Destination) LoopWritingLogs() { if err != nil { // Increment the number of errors while trying to write to log d.counter.Inc() - fmt.Fprintf(os.Stderr, "Failed to write to log: %v", err) } ql.OnLogDone() } @@ -441,7 +504,8 @@ func (h *BackgroundHook) Fire(entry *log.Entry) (err error) { if entry.Level >= log.DebugLevel && h.debugFileNameRE != nil { // This is a debug log, check if debug logging is enabled for this file. - if fileName, ok := entry.Data[fieldFileName]; !ok || !h.debugFileNameRE.MatchString(fileName.(string)) { + fileName, _ := getFileInfo(entry) + if fileName == FileNameUnknown || !h.debugFileNameRE.MatchString(fileName) { return nil } } @@ -557,7 +621,6 @@ var confForTestingOnce sync.Once func ConfigureLoggingForTestingT(t *testing.T) { confForTestingOnce.Do(func() { log.SetFormatter(&Formatter{Component: "test"}) - log.AddHook(ContextHook{}) }) t.Cleanup(RedirectLogrusToTestingT(t)) } diff --git a/libcalico-go/lib/logutils/logutils_test.go b/libcalico-go/lib/logutils/logutils_test.go index c626f975050..2ed5cfbc83f 100644 --- a/libcalico-go/lib/logutils/logutils_test.go +++ b/libcalico-go/lib/logutils/logutils_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import ( "io" "os" "regexp" + "runtime" "strings" "sync" "testing" @@ -29,7 +30,9 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" + "github.com/onsi/gomega/format" "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" . "github.com/projectcalico/calico/libcalico-go/lib/logutils" @@ -44,32 +47,19 @@ var ( func init() { prometheus.MustRegister(testCounter) + format.TruncatedDiff = false } var _ = Describe("Logutils", func() { - ourHook := ContextHook{} var savedWriter io.Writer var buf *bytes.Buffer BeforeEach(func() { - log.AddHook(ourHook) savedWriter = log.StandardLogger().Out buf = &bytes.Buffer{} log.StandardLogger().Out = buf }) AfterEach(func() { log.StandardLogger().Out = savedWriter - levelHooks := log.StandardLogger().Hooks - for level, hooks := range levelHooks { - j := 0 - for _, hook := range hooks { - if hook == ourHook { - continue - } - hooks[j] = hook - j += 1 - } - levelHooks[level] = hooks[:len(hooks)-1] - } }) It("Should add correct file when invoked via log.Info", func() { @@ -84,6 +74,12 @@ var _ = Describe("Logutils", func() { log.WithField("foo", "bar").Info("Test log") Expect(buf.String()).To(ContainSubstring("logutils_test.go")) }) + It("requires logrus.AllLevels to be consistent/in order", func() { + // Formatter.init() pre-computes various strings on this assumption. + for idx, level := range log.AllLevels { + Expect(int(level)).To(Equal(idx)) + } + }) }) var _ = DescribeTable("Formatter", @@ -102,9 +98,11 @@ var _ = DescribeTable("Formatter", log.Entry{ Level: log.InfoLevel, Time: theTime(), + Caller: &runtime.Frame{ + File: "biff.com/bar/foo.go", + Line: 123, + }, Data: log.Fields{ - "__file__": "foo.go", - "__line__": 123, "__flush__": true, // Internal value, should be ignored. }, Message: "The answer is 42.", @@ -116,13 +114,15 @@ var _ = DescribeTable("Formatter", log.Entry{ Level: log.WarnLevel, Time: theTime(), + Caller: &runtime.Frame{ + File: "biff.com/bar/foo.go", + Line: 123, + }, Data: log.Fields{ - "__file__": "foo.go", - "__line__": 123, - "a": 10, - "b": "foobar", - "c": theTime(), - "err": errors.New("an error"), + "a": 10, + "b": "foobar", + "c": theTime(), + "err": errors.New("an error"), }, Message: "The answer is 42.", }, @@ -178,7 +178,7 @@ var _ = Describe("BackgroundHook log flushing tests", func() { bh = NewBackgroundHook(log.AllLevels, log.DebugLevel, []*Destination{testDest}, counter, hookOpts...) logger = log.New() - logger.AddHook(ContextHook{}) + logger.SetReportCaller(true) logger.AddHook(bh) logger.SetLevel(log.DebugLevel) @@ -572,3 +572,52 @@ func BenchmarkRegexpStar(b *testing.B) { BenchOut = BenchOut != re.MatchString("endpoint_mgr.go") } } + +// FuzzAppendTime fuzzes AppendTime against the stdlib time.Time.AppendFormat +// to make sure they agree. +func FuzzAppendTime(f *testing.F) { + pool := sync.Pool{ + New: func() any { + return &bytes.Buffer{} + }, + } + + tFormat := "2006-01-02 15:04:05.000" + var zeroTime time.Time + f.Add(int(zeroTime.Unix()), int(zeroTime.Nanosecond())) + f.Add(0, 0) + // time.Now() at time of writing with various nanos. + f.Add(1257894000, 0) + f.Add(1257894000, 1) + f.Add(1257894000, 100) + f.Add(1257894000, 1000) + f.Add(1257894000, 10000) + f.Add(1257894000, 100000) + f.Add(1257894000, 112345) + f.Fuzz(func(t *testing.T, secs, nanos int) { + timeVal := time.Unix(int64(secs), int64(nanos)) + buf1 := pool.Get().(*bytes.Buffer) + buf2 := pool.Get().(*bytes.Buffer) + { + buf1.Write(timeVal.AppendFormat(buf1.AvailableBuffer(), tFormat)) + AppendTime(buf2, timeVal) + if !bytes.Equal(buf1.Bytes(), buf2.Bytes()) { + t.Fatalf("Expected %s, got %s", buf1.String(), buf2.String()) + } + buf1.Reset() + buf2.Reset() + } + { + utc := timeVal.UTC() + buf1.Write(utc.AppendFormat(buf1.AvailableBuffer(), tFormat)) + AppendTime(buf2, utc) + if !bytes.Equal(buf1.Bytes(), buf2.Bytes()) { + t.Fatalf("UTC: Expected %s, got %s", buf1.String(), buf2.String()) + } + buf1.Reset() + buf2.Reset() + } + pool.Put(buf1) + pool.Put(buf2) + }) +} diff --git a/libcalico-go/lib/names/policy.go b/libcalico-go/lib/names/policy.go new file mode 100644 index 00000000000..a7561dc03b7 --- /dev/null +++ b/libcalico-go/lib/names/policy.go @@ -0,0 +1,134 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package names + +import ( + "errors" + "fmt" + "strings" +) + +const ( + DefaultTierName = "default" + AdminNetworkPolicyTierName = "adminnetworkpolicy" + + K8sNetworkPolicyNamePrefix = "knp.default." + K8sAdminNetworkPolicyNamePrefix = "kanp.adminnetworkpolicy." + OssNetworkPolicyNamePrefix = "ossg." +) + +// TierFromPolicyName extracts the tier from a tiered policy name. +// If the policy is a K8s policy (with prefix "knp.default"), then tier name is +// is the "default" tier. If there are no tier name prefix, then again the +// "default" tier name is returned. +// Otherwise, the first full word that occurs before the first "." (dot) is returned +// as the tier value. +func TierFromPolicyName(name string) (string, error) { + if name == "" { + return "", errors.New("Tiered policy name is empty") + } + // If it is a K8s (admin) network policy, then simply return the policy name as is. + if strings.HasPrefix(name, K8sNetworkPolicyNamePrefix) { + return DefaultTierName, nil + } + if strings.HasPrefix(name, K8sAdminNetworkPolicyNamePrefix) { + return AdminNetworkPolicyTierName, nil + } + parts := strings.SplitN(name, ".", 2) + if len(parts) < 2 { + // A name without a prefix. + return DefaultTierName, nil + } + // Return the first word before the first dot. + return parts[0], nil +} + +// BackendTieredPolicyName returns a policy name suitable for use by any +// backend. It will always return a policy name prefixed with the appropriate +// tier or error. The tier name is passed in as-is from the Policy Spec of a +// (Staged)NetworkPolicy or a (Staged)GlobalNetworkPolicy resource. +func BackendTieredPolicyName(policy, tier string) (string, error) { + tieredPolicy := TieredPolicyName(policy) + return tieredPolicy, validateBackendTieredPolicyName(tieredPolicy, tier) +} + +func validateBackendTieredPolicyName(policy, tier string) error { + if policy == "" { + return errors.New("Policy name is empty") + } + if policyNameIsFormatted(policy) { + return nil + } + + t := TierOrDefault(tier) + parts := strings.SplitN(policy, ".", 2) + if len(parts) != 2 || !strings.HasPrefix(policy, t+".") { + return fmt.Errorf("Incorrectly formatted policy name %s", policy) + } + return nil +} + +func TieredPolicyName(policy string) string { + if policy == "" { + return "" + } + if policyNameIsFormatted(policy) { + return policy + } + + parts := strings.SplitN(policy, ".", 2) + if len(parts) == 1 { + // Default tier name. + return fmt.Sprintf("default.%v", policy) + } else if len(parts) == 2 { + // The policy name is already prefixed appropriately. + return policy + } + return "" +} + +// ClientTieredPolicyName returns a policy name suitable for returning to +// the user of the client. The tier name is passed in as-is from the Policy +// spec for (Staged)NetworkPolicy or a (Staged)GlobalNetworkPolicy. +func ClientTieredPolicyName(policy string) (string, error) { + if policy == "" { + return "", errors.New("Policy name is empty") + } + if policyNameIsFormatted(policy) { + return policy, nil + } + parts := strings.SplitN(policy, ".", 2) + if len(parts) != 2 { + return "", fmt.Errorf("Invalid policy name %s", policy) + } else if parts[0] == DefaultTierName { + return parts[1], nil + } + return policy, nil +} + +func policyNameIsFormatted(policy string) bool { + // If it is a K8s (admin) network policy or OSSG, we expect the policy name to be formatted properly in the first place. + return strings.HasPrefix(policy, K8sNetworkPolicyNamePrefix) || strings.HasPrefix(policy, K8sAdminNetworkPolicyNamePrefix) || + strings.HasPrefix(policy, OssNetworkPolicyNamePrefix) +} + +// TierOrDefault returns the tier name, or the default if blank. +func TierOrDefault(tier string) string { + if len(tier) == 0 { + return DefaultTierName + } else { + return tier + } +} diff --git a/libcalico-go/lib/names/policy_test.go b/libcalico-go/lib/names/policy_test.go new file mode 100644 index 00000000000..277bb5dd859 --- /dev/null +++ b/libcalico-go/lib/names/policy_test.go @@ -0,0 +1,90 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package names_test + +import ( + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" + + "github.com/projectcalico/calico/libcalico-go/lib/names" +) + +var _ = DescribeTable("Parse Tiered policy name", + func(policy string, expectError bool, expectedTier string) { + tier, err := names.TierFromPolicyName(policy) + if expectError { + Expect(err).To(HaveOccurred()) + } else { + Expect(err).NotTo(HaveOccurred()) + Expect(tier).To(Equal(expectedTier)) + } + }, + Entry("Empty policy name", "", true, ""), + Entry("K8s network policy", "knp.default.foopolicy", false, "default"), + Entry("K8s admin network policy", "kanp.adminnetworkpolicy.barpolicy", false, "adminnetworkpolicy"), + Entry("Policy name without tier", "foopolicy", false, "default"), + Entry("Correct tiered policy name", "baztier.foopolicy", false, "baztier"), +) + +var _ = DescribeTable("Backend Tiered policy name", + func(policy, tier string, expectError bool, expectedTpn string) { + tpn, err := names.BackendTieredPolicyName(policy, tier) + if expectError { + Expect(err).To(HaveOccurred()) + } else { + Expect(err).NotTo(HaveOccurred()) + Expect(tpn).To(Equal(expectedTpn)) + } + }, + Entry("Empty policy name", "", "foo", true, ""), + Entry("Empty tier spec with correctly formatted name", "footier.bazpolicy", "", true, ""), + Entry("Tier spec present with incorrectly formatted name", "bazpolicy", "footier", true, ""), + Entry("Correcty formatted tiered policy name but not matching tier spec", "footier.bazpolicy", "baztier", true, ""), + Entry("K8s Network Policy and empty tier", "knp.default.foobar", "", false, "knp.default.foobar"), + Entry("K8s Admin Network Policy and empty tier", "kanp.adminnetworkpolicy.foobar", "", false, "kanp.adminnetworkpolicy.foobar"), + Entry("Network Policy and empty tier", "foobar", "", false, "default.foobar"), + Entry("Matching tier spec and correctly formatted tiered policy name", "footier.bazpolicy", "footier", false, "footier.bazpolicy"), +) + +var _ = DescribeTable("Tiered policy name", + func(policy, expectedTpn string) { + tpn := names.TieredPolicyName(policy) + Expect(tpn).To(Equal(expectedTpn)) + }, + Entry("Empty policy name", "", ""), + Entry("Correctly formatted name", "footier.bazpolicy", "footier.bazpolicy"), + Entry("Policy in default tier", "bazpolicy", "default.bazpolicy"), + Entry("Policy in default tier with prefix", "default.bazpolicy", "default.bazpolicy"), + Entry("K8s network policy", "knp.default.bazpolicy", "knp.default.bazpolicy"), + Entry("K8s admin network policy", "kanp.adminnetworkpolicy.foopolicy", "kanp.adminnetworkpolicy.foopolicy"), +) + +var _ = DescribeTable("Client Tiered policy name", + func(policy string, expectError bool, expectedTpn string) { + tpn, err := names.ClientTieredPolicyName(policy) + if expectError { + Expect(err).To(HaveOccurred()) + } else { + Expect(err).NotTo(HaveOccurred()) + Expect(tpn).To(Equal(expectedTpn)) + } + }, + Entry("Empty policy name", "foo", true, ""), + Entry("Incorrectly formatted name", "bazpolicy", true, ""), + Entry("Correctly formatted name", "footier.bazpolicy", false, "footier.bazpolicy"), + Entry("Default tier", "default.bazpolicy", false, "bazpolicy"), + Entry("K8s Network Policy", "knp.default.bazpolicy", false, "knp.default.bazpolicy"), + Entry("K8s Admin Network Policy", "kanp.adminnetworkpolicy.bazpolicy", false, "kanp.adminnetworkpolicy.bazpolicy"), +) diff --git a/libcalico-go/lib/netlinkutils/netlinkutils.go b/libcalico-go/lib/netlinkutils/netlinkutils.go new file mode 100644 index 00000000000..a93b41c7f08 --- /dev/null +++ b/libcalico-go/lib/netlinkutils/netlinkutils.go @@ -0,0 +1,78 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Dummy version of the HCN API for compilation on Linux. +package netlinkutils + +import ( + "errors" + + log "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" +) + +// AddrListRetryEINTR calls netlink's AddrList API and retries for 3 times if the API call +// is interrupted(EINTR returned). This is not an error and the call must be retried. +// AddrListRetryEINTR must be used for listing addresses of an interface in place of netlink's AddrList API. +func AddrListRetryEINTR(nlHandle *netlink.Handle, link netlink.Link, family int) ([]netlink.Addr, error) { + retries := 3 + for { + links, err := nlHandle.AddrList(link, family) + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + log.Debugf("listing address for interface %s hit EINTR. Retrying", link.Attrs().Name) + retries-- + continue + } + } + return links, err + } +} + +// RouteListRetryEINTR calls netlink's RouteList API and retries for 3 times if the API call +// is interrupted(EINTR returned). This is not an error and the call must be retried. +// RouteListRetryEINTR must be used for listing routes of an interface in place of netlink's RouteList API. +func RouteListRetryEINTR(nlHandle *netlink.Handle, link netlink.Link, family int) ([]netlink.Route, error) { + retries := 3 + for { + routes, err := nlHandle.RouteList(link, family) + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + log.Debugf("listing routes for interface %s, family %d hit EINTR. Retrying", link.Attrs().Name, family) + retries-- + continue + } + } + return routes, err + } +} + +// LinkListRetryEINTR calls netlink's LinkList API and retries for 3 times if the API call +// is interrupted(EINTR returned). This is not an error and the call must be retried. +// LinkListRetryEINTR must be used for listing interfaces in place of netlink's LinkList API. +func LinkListRetryEINTR(nlHandle *netlink.Handle) ([]netlink.Link, error) { + retries := 3 + for { + links, err := nlHandle.LinkList() + if err != nil { + if errors.Is(err, unix.EINTR) && retries > 0 { + log.Debug("listing links hit EINTR. Retrying") + retries-- + continue + } + } + return links, err + } +} diff --git a/libcalico-go/lib/resources/tier.go b/libcalico-go/lib/resources/tier.go new file mode 100644 index 00000000000..8b23077635e --- /dev/null +++ b/libcalico-go/lib/resources/tier.go @@ -0,0 +1,35 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resources + +import ( + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" +) + +func DefaultTierFields(res *apiv3.Tier) { + // nil order was allowed before, and it was used for the default tier. + // For the implementation of BaselineAdminNetworkPolicy, we need to add a tier + // after the default one. As such, the default tier order is changed to 1,000,000 from nil. + // To keep the behavior in sync with user defined tiers with nil order, nil order is + // treated similar to the value of 1,000,000. + if res.Spec.Order == nil { + order := apiv3.DefaultTierOrder + res.Spec.Order = &order + } + if res.Spec.DefaultAction == nil { + actionDeny := apiv3.Deny + res.Spec.DefaultAction = &actionDeny + } +} diff --git a/libcalico-go/lib/set/set.go b/libcalico-go/lib/set/set.go index 57d6c6e7b8a..4d3b8dc1da9 100644 --- a/libcalico-go/lib/set/set.go +++ b/libcalico-go/lib/set/set.go @@ -25,6 +25,10 @@ func New[T comparable]() Typed[T] { return make(Typed[T]) } +func NewSize[T comparable](size int) Typed[T] { + return make(Typed[T], size) +} + // Empty returns a read-only set with no members. Calls to Add etc. panic. func Empty[T comparable]() Typed[T] { return (Typed[T])(nil) diff --git a/libcalico-go/lib/testutils/createRule.go b/libcalico-go/lib/testutils/createRule.go index 7ba1e8206d1..a82a79204f9 100644 --- a/libcalico-go/lib/testutils/createRule.go +++ b/libcalico-go/lib/testutils/createRule.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ func CreateRule(ipv, icmpType, icmpCode int, proto, cidrStr, tag, selector, inAc src := api.EntityRule{ Tag: tag, Net: &cnet.IPNet{ - *cidr, + IPNet: *cidr, }, Selector: selector, } diff --git a/libcalico-go/lib/testutils/e2e_describe.go b/libcalico-go/lib/testutils/e2e_describe.go index f1fc9f21bf9..99b585ec539 100644 --- a/libcalico-go/lib/testutils/e2e_describe.go +++ b/libcalico-go/lib/testutils/e2e_describe.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017,2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,10 +15,12 @@ package testutils import ( "fmt" + "os" "github.com/projectcalico/calico/libcalico-go/lib/apiconfig" . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) type DatastoreType int @@ -72,3 +74,17 @@ func E2eDatastoreDescribe(description string, datastores DatastoreType, body fun return true } + +// GetK8sInlineConfig returns a CalicoAPIConfig with the kubeconfig inline. +func GetK8sInlineConfig() apiconfig.CalicoAPIConfig { + kc, err := os.ReadFile(kubeconfig) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + return apiconfig.CalicoAPIConfig{ + Spec: apiconfig.CalicoAPIConfigSpec{ + DatastoreType: apiconfig.Kubernetes, + KubeConfig: apiconfig.KubeConfig{ + KubeconfigInline: string(kc), + }, + }, + } +} diff --git a/libcalico-go/lib/testutils/ginkgolog.go b/libcalico-go/lib/testutils/ginkgolog.go index ea095e67c6b..8e426002db3 100644 --- a/libcalico-go/lib/testutils/ginkgolog.go +++ b/libcalico-go/lib/testutils/ginkgolog.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,18 +11,20 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + package testutils import ( "github.com/onsi/ginkgo" + "github.com/sirupsen/logrus" "github.com/projectcalico/calico/libcalico-go/lib/logutils" ) func HookLogrusForGinkgo() { - logrus.AddHook(logutils.ContextHook{}) - logrus.SetFormatter(&logutils.Formatter{}) + // Set up logging formatting. + logutils.ConfigureFormatter("test") logrus.SetOutput(ginkgo.GinkgoWriter) logrus.SetLevel(logrus.DebugLevel) } diff --git a/libcalico-go/lib/testutils/resources.go b/libcalico-go/lib/testutils/resources.go index d79980d9523..61afb9c30ef 100644 --- a/libcalico-go/lib/testutils/resources.go +++ b/libcalico-go/lib/testutils/resources.go @@ -208,7 +208,7 @@ func (t *testResourceWatcher) expectEvents(kind string, anyOrder bool, expectedE // events, so protect against that scenario - we'll check later once we've // constructed useful diagnostics. var actualEvents []watch.Event - log.Infof("Received %s events, expected %d", len(t.events), len(expectedEvents)) + log.Infof("Received %d events, expected %d", len(t.events), len(expectedEvents)) if len(t.events) != len(expectedEvents) { // Log out the events we received before failing the test. log.Errorf("Number of received events does not match expected.") diff --git a/libcalico-go/lib/testutils/syncertester.go b/libcalico-go/lib/testutils/syncertester.go index d36f14863ed..7b2b668806e 100644 --- a/libcalico-go/lib/testutils/syncertester.go +++ b/libcalico-go/lib/testutils/syncertester.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + package testutils import ( @@ -27,6 +28,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + log "github.com/sirupsen/logrus" gomegatypes "github.com/onsi/gomega/types" @@ -327,7 +329,7 @@ func (st *SyncerTester) hasUpdates(expectedUpdates []api.Update, checkOrder bool updateAsKey := func(update api.Update) string { path, err := model.KeyToDefaultPath(update.Key) Expect(err).NotTo(HaveOccurred()) - return fmt.Sprintf("%s;%s", update.UpdateType, path) + return fmt.Sprintf("%d;%s", update.UpdateType, path) } // removeFromActualUpdatesMap removes the update from the map, and returns an error if not found. It will remove @@ -546,7 +548,7 @@ func updatesEqual(actual, expected api.Update) bool { // update - this makes writing tests simpler. func kvpsEqual(actual, expected model.KVPair) bool { if !reflect.DeepEqual(expected.Key, actual.Key) { - log.Debug("Keys are not equal: %#v != %#v", expected.Key, actual.Key) + log.Debugf("Keys are not equal: %#v != %#v", expected.Key, actual.Key) return false } if expected.UID != nil && (actual.UID == nil || *actual.UID != *expected.UID) { diff --git a/libcalico-go/lib/upgrade/converters/node.go b/libcalico-go/lib/upgrade/converters/node.go index ac02bd40ed8..1959ddec38f 100644 --- a/libcalico-go/lib/upgrade/converters/node.go +++ b/libcalico-go/lib/upgrade/converters/node.go @@ -49,11 +49,11 @@ func (n Node) APIV1ToBackendV1(a unversioned.Resource) (*model.KVPair, error) { return nil, fmt.Errorf("Invalid NodeBGPSpec, missing address: %v", an.Spec.BGP) } if an.Spec.BGP.IPv4Address != nil { - v.BGPIPv4Addr = &cnet.IP{an.Spec.BGP.IPv4Address.IP} + v.BGPIPv4Addr = &cnet.IP{IP: an.Spec.BGP.IPv4Address.IP} v.BGPIPv4Net = an.Spec.BGP.IPv4Address.Network() } if an.Spec.BGP.IPv6Address != nil { - v.BGPIPv6Addr = &cnet.IP{an.Spec.BGP.IPv6Address.IP} + v.BGPIPv6Addr = &cnet.IP{IP: an.Spec.BGP.IPv6Address.IP} v.BGPIPv6Net = an.Spec.BGP.IPv6Address.Network() } v.BGPASNumber = an.Spec.BGP.ASNumber diff --git a/libcalico-go/lib/upgrade/converters/policy.go b/libcalico-go/lib/upgrade/converters/policy.go index c54109f8a1c..b7bc470147e 100644 --- a/libcalico-go/lib/upgrade/converters/policy.go +++ b/libcalico-go/lib/upgrade/converters/policy.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ func (_ Policy) APIV1ToBackendV1(a unversioned.Resource) (*model.KVPair, error) d := model.KVPair{ Key: model.PolicyKey{ Name: ap.Metadata.Name, + Tier: ap.Metadata.Tier, }, Value: &model.Policy{ Order: ap.Spec.Order, @@ -102,8 +103,13 @@ func (_ Policy) BackendV1ToAPIV3(kvp *model.KVPair) (Resource, error) { } ap := apiv3.NewGlobalNetworkPolicy() - ap.Name = convertNameNoDots(bk.Name) + tier := convertNameNoDots(bk.Tier) + if tier == "" { + tier = "default" + } + ap.Name = tier + "." + convertNameNoDots(bk.Name) ap.Annotations = bp.Annotations + ap.Labels = map[string]string{apiv3.LabelTier: tier} ap.Spec.Order = bp.Order ap.Spec.Ingress = rulesV1BackendToV3API(bp.InboundRules) ap.Spec.Egress = rulesV1BackendToV3API(bp.OutboundRules) @@ -112,6 +118,7 @@ func (_ Policy) BackendV1ToAPIV3(kvp *model.KVPair) (Resource, error) { ap.Spec.PreDNAT = bp.PreDNAT ap.Spec.ApplyOnForward = bp.ApplyOnForward ap.Spec.Types = nil // Set later. + ap.Spec.Tier = tier if !bp.ApplyOnForward && (bp.DoNotTrack || bp.PreDNAT) { // This case happens when there is a preexisting policy in the datastore, from before diff --git a/libcalico-go/lib/upgrade/converters/policy_test.go b/libcalico-go/lib/upgrade/converters/policy_test.go index 6b383720e99..0f3a4f9a6d1 100644 --- a/libcalico-go/lib/upgrade/converters/policy_test.go +++ b/libcalico-go/lib/upgrade/converters/policy_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ var policyTable = []TableEntry{ &apiv1.Policy{ Metadata: apiv1.PolicyMetadata{ Name: "nameyMcPolicyName", + Tier: "tieryMcTierFace", }, Spec: apiv1.PolicySpec{ Order: &order1, @@ -47,6 +48,7 @@ var policyTable = []TableEntry{ &model.KVPair{ Key: model.PolicyKey{ Name: "nameyMcPolicyName", + Tier: "tieryMcTierFace", }, Value: &model.Policy{ Order: &order1, @@ -61,7 +63,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "nameymcpolicyname-32df456f", + Name: "tierymctierface-df3092e8.nameymcpolicyname-32df456f", + Labels: map[string]string{apiv3.LabelTier: "tierymctierface-df3092e8"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -72,6 +75,7 @@ var policyTable = []TableEntry{ PreDNAT: true, ApplyOnForward: true, Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "tierymctierface-df3092e8", }, }, ), @@ -79,6 +83,7 @@ var policyTable = []TableEntry{ &apiv1.Policy{ Metadata: apiv1.PolicyMetadata{ Name: "MaKe.-.MaKe", + Tier: "TiEr.-.TiEr", }, Spec: apiv1.PolicySpec{ Order: &order1, @@ -93,6 +98,7 @@ var policyTable = []TableEntry{ &model.KVPair{ Key: model.PolicyKey{ Name: "MaKe.-.MaKe", + Tier: "TiEr.-.TiEr", }, Value: &model.Policy{ Order: &order1, @@ -107,7 +113,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "make-make-1b6971c8", + Name: "tier-tier-dcb6465f.make-make-1b6971c8", + Labels: map[string]string{apiv3.LabelTier: "tier-tier-dcb6465f"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -118,13 +125,15 @@ var policyTable = []TableEntry{ PreDNAT: false, ApplyOnForward: true, Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "tier-tier-dcb6465f", }, }, ), - Entry("policy with PreDNAT set to true should convert ApplyOnForward to true in v3 API", + Entry("explicit default tier policy with PreDNAT set to true should convert ApplyOnForward to true in v3 API", &apiv1.Policy{ Metadata: apiv1.PolicyMetadata{ Name: "RAWR", + Tier: "default", }, Spec: apiv1.PolicySpec{ Order: &order1, @@ -136,6 +145,7 @@ var policyTable = []TableEntry{ &model.KVPair{ Key: model.PolicyKey{ Name: "RAWR", + Tier: "default", }, Value: &model.Policy{ Order: &order1, @@ -149,7 +159,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "rawr-03d81e1d", + Name: "default.rawr-03d81e1d", + Labels: map[string]string{apiv3.LabelTier: "default"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -159,6 +170,7 @@ var policyTable = []TableEntry{ PreDNAT: true, ApplyOnForward: true, // notice this gets converted to true, because PreDNAT are true. Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "default", }, }, ), @@ -191,7 +203,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "rawr-03d81e1d", + Name: "default.rawr-03d81e1d", + Labels: map[string]string{apiv3.LabelTier: "default"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -201,6 +214,7 @@ var policyTable = []TableEntry{ PreDNAT: false, ApplyOnForward: true, // notice this gets converted to true, because DoNotTrack are true. Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "default", }, }, ), @@ -233,7 +247,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "meow", + Name: "default.meow", + Labels: map[string]string{apiv3.LabelTier: "default"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -243,6 +258,7 @@ var policyTable = []TableEntry{ PreDNAT: false, ApplyOnForward: false, Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "default", }, }, ), @@ -280,7 +296,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "make-make-1b6971c8", + Name: "default.make-make-1b6971c8", + Labels: map[string]string{apiv3.LabelTier: "default"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -292,6 +309,7 @@ var policyTable = []TableEntry{ PreDNAT: false, ApplyOnForward: true, Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress, apiv3.PolicyTypeEgress}, + Tier: "default", }, }, ), @@ -332,7 +350,8 @@ var policyTable = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "policy1", + Name: "default.policy1", + Labels: map[string]string{apiv3.LabelTier: "default"}, }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -346,6 +365,7 @@ var policyTable = []TableEntry{ Egress: []apiv3.Rule{}, Selector: "type=='database'", Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "default", }, }, ), @@ -391,7 +411,7 @@ var policyTableBackend = []TableEntry{ }, apiv3.GlobalNetworkPolicy{ ObjectMeta: v1.ObjectMeta{ - Name: "somekey", + Name: "default.somekey", }, Spec: apiv3.GlobalNetworkPolicySpec{ Order: &order1, @@ -403,6 +423,7 @@ var policyTableBackend = []TableEntry{ PreDNAT: true, ApplyOnForward: true, Types: []apiv3.PolicyType{apiv3.PolicyTypeIngress}, + Tier: "default", }, }, ), diff --git a/libcalico-go/lib/upgrade/converters/tier.go b/libcalico-go/lib/upgrade/converters/tier.go new file mode 100644 index 00000000000..99707a2ef68 --- /dev/null +++ b/libcalico-go/lib/upgrade/converters/tier.go @@ -0,0 +1,74 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package converters + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + apiv1 "github.com/projectcalico/calico/libcalico-go/lib/apis/v1" + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" +) + +// Tier implements the Converter interface. +type Tier struct{} + +// APIV1ToBackendV1 converts v1 Tier API to v1 Tier KVPair. +func (_ Tier) APIV1ToBackendV1(a unversioned.Resource) (*model.KVPair, error) { + ap := a.(*apiv1.Tier) + + d := model.KVPair{ + Key: model.TierKey{ + Name: ap.Metadata.Name, + }, + Value: &model.Tier{ + Order: ap.Spec.Order, + }, + } + + log.WithFields(log.Fields{ + "APIv1": ap, + "KVPair": d, + }).Debugf("Converted Tier: '%s' V1 API to V1 backend", ap.Metadata.Name) + + return &d, nil +} + +// BackendV1ToAPIV3 converts v1 Tier KVPair to v3 API. +func (_ Tier) BackendV1ToAPIV3(kvp *model.KVPair) (Resource, error) { + bp, ok := kvp.Value.(*model.Tier) + if !ok { + return nil, fmt.Errorf("value is not a valid Tier resource") + } + bk, ok := kvp.Key.(model.TierKey) + if !ok { + return nil, fmt.Errorf("value is not a valid Tier resource key") + } + + ap := apiv3.NewTier() + ap.Name = convertName(bk.Name) + ap.Spec.Order = bp.Order + + log.WithFields(log.Fields{ + "KVPairV1": bp, + "APIv3": ap, + }).Debugf("Converted Tier: '%s' V1 backend to V3 API", ap.Name) + + return ap, nil +} diff --git a/libcalico-go/lib/upgrade/converters/tier_test.go b/libcalico-go/lib/upgrade/converters/tier_test.go new file mode 100644 index 00000000000..632991c3272 --- /dev/null +++ b/libcalico-go/lib/upgrade/converters/tier_test.go @@ -0,0 +1,87 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package converters + +import ( + "testing" + + . "github.com/onsi/gomega" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3" + + apiv1 "github.com/projectcalico/calico/libcalico-go/lib/apis/v1" + "github.com/projectcalico/calico/libcalico-go/lib/apis/v1/unversioned" + "github.com/projectcalico/calico/libcalico-go/lib/backend/model" +) + +var order17 = 17.0 +var tierTable = []struct { + description string + v1API unversioned.Resource + v1KVP *model.KVPair + v3API apiv3.Tier +}{ + { + description: "fully populated Tier", + v1API: &apiv1.Tier{ + Metadata: apiv1.TierMetadata{ + Name: "nameyMcTierName", + }, + Spec: apiv1.TierSpec{ + Order: &order17, + }, + }, + v1KVP: &model.KVPair{ + Key: model.TierKey{ + Name: "nameyMcTierName", + }, + Value: &model.Tier{ + Order: &order17, + }, + }, + v3API: apiv3.Tier{ + ObjectMeta: v1.ObjectMeta{ + Name: "nameymctiername-b645ff6a", + }, + Spec: apiv3.TierSpec{ + Order: &order17, + }, + }, + }, +} + +func TestCanConvertV1ToV3Tier(t *testing.T) { + + for _, entry := range tierTable { + t.Run(entry.description, func(t *testing.T) { + RegisterTestingT(t) + + p := Tier{} + + // Test and assert v1 API to v1 backend logic. + v1KVPResult, err := p.APIV1ToBackendV1(entry.v1API) + Expect(err).NotTo(HaveOccurred(), entry.description) + Expect(v1KVPResult.Key.(model.TierKey).Name).To(Equal(entry.v1KVP.Key.(model.TierKey).Name)) + Expect(v1KVPResult.Value.(*model.Tier)).To(Equal(entry.v1KVP.Value)) + + // Test and assert v1 backend to v3 API logic. + v3APIResult, err := p.BackendV1ToAPIV3(entry.v1KVP) + Expect(err).NotTo(HaveOccurred(), entry.description) + Expect(v3APIResult.(*apiv3.Tier).Name).To(Equal(entry.v3API.Name), entry.description) + Expect(v3APIResult.(*apiv3.Tier).Spec).To(Equal(entry.v3API.Spec), entry.description) + }) + } +} diff --git a/libcalico-go/lib/upgrade/converters/workloadendpoint_test.go b/libcalico-go/lib/upgrade/converters/workloadendpoint_test.go index 8941c9a56db..9524e158b64 100644 --- a/libcalico-go/lib/upgrade/converters/workloadendpoint_test.go +++ b/libcalico-go/lib/upgrade/converters/workloadendpoint_test.go @@ -452,7 +452,7 @@ func makeMac() *net.MAC { if err != nil { panic(err) } - return &net.MAC{mac} + return &net.MAC{HardwareAddr: mac} } func makeEndpointPortsV1() []apiv1.EndpointPort { diff --git a/libcalico-go/lib/upgrade/migrator/migrate.go b/libcalico-go/lib/upgrade/migrator/migrate.go index 25e44a4e863..033386c3787 100644 --- a/libcalico-go/lib/upgrade/migrator/migrate.go +++ b/libcalico-go/lib/upgrade/migrator/migrate.go @@ -474,6 +474,18 @@ func (m *migrationHelper) queryAndConvertResources() (*MigrationData, error) { } } + if m.clientv1.IsKDD() { + m.statusBullet("skipping Tier resources - these do not need migrating") + } else { + m.statusBullet("handling Tier resources") + // Query and convert the Tiers + if err := m.queryAndConvertV1ToV3Resources( + data, model.TierListOptions{}, converters.Tier{}, noFilter, + ); err != nil { + return nil, err + } + } + if m.clientv1.IsKDD() { m.statusBullet("skipping GlobalNetworkPolicy resources - these do not need migrating") } else { diff --git a/libcalico-go/lib/upgrade/migrator/migrate_test.go b/libcalico-go/lib/upgrade/migrator/migrate_test.go index d59c7d4b593..38960d32bab 100644 --- a/libcalico-go/lib/upgrade/migrator/migrate_test.go +++ b/libcalico-go/lib/upgrade/migrator/migrate_test.go @@ -99,7 +99,7 @@ var _ = Describe("Test OpenStack migration filters", func() { State: "Running", Name: "wepName", ActiveInstanceID: "wepActInstID", - Mac: &net.MAC{mac}, + Mac: &net.MAC{HardwareAddr: mac}, ProfileIDs: []string{"wepProfIDs"}, IPv4Nets: []net.IPNet{}, IPv6Nets: []net.IPNet{}, diff --git a/libcalico-go/lib/validator/v1/common.go b/libcalico-go/lib/validator/v1/common.go index 43c2266b80c..e1c4030a3c1 100644 --- a/libcalico-go/lib/validator/v1/common.go +++ b/libcalico-go/lib/validator/v1/common.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -57,6 +57,10 @@ func ValidateMetadataIDsAssigned(rm unversioned.ResourceMetadata) error { if metadata.Name == "" { return errors.ErrorInsufficientIdentifiers{Name: "name"} } + case api.TierMetadata: + if metadata.Name == "" { + return errors.ErrorInsufficientIdentifiers{Name: "name"} + } case api.ProfileMetadata: if metadata.Name == "" { return errors.ErrorInsufficientIdentifiers{Name: "name"} diff --git a/libcalico-go/lib/validator/v1/common_test.go b/libcalico-go/lib/validator/v1/common_test.go index 217ccb58563..7c9e32df111 100644 --- a/libcalico-go/lib/validator/v1/common_test.go +++ b/libcalico-go/lib/validator/v1/common_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -128,6 +128,28 @@ var _ = Describe("Test ValidateMetadataIDsAssigned function", func() { err := validator.ValidateMetadataIDsAssigned(policy.Metadata) Expect(err).NotTo(HaveOccurred()) }) + It("should pass with a Name and Tier specified", func() { + policy.Metadata.Tier = "notdefault" + err := validator.ValidateMetadataIDsAssigned(policy.Metadata) + Expect(err).NotTo(HaveOccurred()) + }) + }) + + Context("with Tier Metadata", func() { + var tier *api.Tier + BeforeEach(func() { + tier = api.NewTier() + tier.Metadata.Name = "testTier" + }) + It("should fail if missing Name", func() { + tier.Metadata.Name = "" + err := validator.ValidateMetadataIDsAssigned(tier.Metadata) + Expect(err).To(HaveOccurred()) + }) + It("should pass with a Name specified", func() { + err := validator.ValidateMetadataIDsAssigned(tier.Metadata) + Expect(err).NotTo(HaveOccurred()) + }) }) Context("with Profile Metadata", func() { diff --git a/libcalico-go/lib/validator/v3/validator.go b/libcalico-go/lib/validator/v3/validator.go index c5671a99e05..95bad004a02 100644 --- a/libcalico-go/lib/validator/v3/validator.go +++ b/libcalico-go/lib/validator/v3/validator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2023 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ import ( libapi "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" "github.com/projectcalico/calico/libcalico-go/lib/errors" + "github.com/projectcalico/calico/libcalico-go/lib/names" cnet "github.com/projectcalico/calico/libcalico-go/lib/net" "github.com/projectcalico/calico/libcalico-go/lib/selector" "github.com/projectcalico/calico/libcalico-go/lib/set" @@ -61,15 +62,21 @@ var ( // more restrictive naming requirements. nameRegex = regexp.MustCompile("^" + nameSubdomainFmt + "$") + // Tiers must have simple names with no dots, since they appear as sub-components of other + // names. + tierNameRegex = regexp.MustCompile("^" + nameLabelFmt + "$") + containerIDFmt = "[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?" containerIDRegex = regexp.MustCompile("^" + containerIDFmt + "$") // NetworkPolicy names must either be a simple DNS1123 label format (nameLabelFmt), or + // nameLabelFmt.nameLabelFmt (with a single dot), or // must be the standard name format (nameRegex) prefixed with "knp.default" or "ossg.default". - networkPolicyNameRegex = regexp.MustCompile("^((" + nameLabelFmt + ")|((?:knp|ossg)\\.default\\.(" + nameSubdomainFmt + ")))$") + networkPolicyNameRegex = regexp.MustCompile("^((" + nameLabelFmt + ")(\\." + nameLabelFmt + ")?|((?:knp|ossg)\\.default\\.(" + nameSubdomainFmt + ")))$") - // GlobalNetworkPolicy names must be a simple DNS1123 label format (nameLabelFmt). - globalNetworkPolicyNameRegex = regexp.MustCompile("^(" + nameLabelFmt + ")$") + // GlobalNetworkPolicy names must be a simple DNS1123 label format (nameLabelFmt) or + // have a single dot. + globalNetworkPolicyNameRegex = regexp.MustCompile("^(" + nameLabelFmt + "\\.)?" + nameLabelFmt + "$") // Hostname have to be valid ipv4, ipv6 or strings up to 64 characters. prometheusHostRegexp = regexp.MustCompile(`^[a-zA-Z0-9:._+-]{1,64}$`) @@ -80,6 +87,8 @@ var ( interfaceRegex = regexp.MustCompile("^[a-zA-Z0-9_.-]{1,15}$") bgpFilterInterfaceRegex = regexp.MustCompile("^[a-zA-Z0-9_.*-]{1,15}$") + bgpFilterPrefixLengthV4 = regexp.MustCompile("^([0-9]|[12][0-9]|3[0-2])$") + bgpFilterPrefixLengthV6 = regexp.MustCompile("^([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$") ignoredInterfaceRegex = regexp.MustCompile("^[a-zA-Z0-9_.*-]{1,15}$") ifaceFilterRegex = regexp.MustCompile("^[a-zA-Z0-9:._+-]{1,15}$") actionRegex = regexp.MustCompile("^(Allow|Deny|Log|Pass)$") @@ -163,6 +172,8 @@ func init() { registerFieldValidator("action", validateAction) registerFieldValidator("interface", validateInterface) registerFieldValidator("bgpFilterInterface", validateBGPFilterInterface) + registerFieldValidator("bgpFilterPrefixLengthV4", validateBGPFilterPrefixLengthV4) + registerFieldValidator("bgpFilterPrefixLengthV6", validateBGPFilterPrefixLengthV6) registerFieldValidator("ignoredInterface", validateIgnoredInterface) registerFieldValidator("datastoreType", validateDatastoreType) registerFieldValidator("name", validateName) @@ -233,6 +244,7 @@ func init() { registerStructValidator(validate, validateNodeSpec, libapi.NodeSpec{}) registerStructValidator(validate, validateIPAMConfigSpec, libapi.IPAMConfigSpec{}) registerStructValidator(validate, validateObjectMeta, metav1.ObjectMeta{}) + registerStructValidator(validate, validateTier, api.Tier{}) registerStructValidator(validate, validateHTTPRule, api.HTTPMatch{}) registerStructValidator(validate, validateFelixConfigSpec, api.FelixConfigurationSpec{}) registerStructValidator(validate, validateWorkloadEndpointSpec, libapi.WorkloadEndpointSpec{}) @@ -302,6 +314,18 @@ func validateBGPFilterInterface(fl validator.FieldLevel) bool { return s == "*" || bgpFilterInterfaceRegex.MatchString(s) } +func validateBGPFilterPrefixLengthV4(fl validator.FieldLevel) bool { + s := fmt.Sprint(fl.Field()) + log.Debugf("Validate BGPFilter PrefixLength v4: %s", s) + return s == "*" || bgpFilterPrefixLengthV4.MatchString(s) +} + +func validateBGPFilterPrefixLengthV6(fl validator.FieldLevel) bool { + s := fmt.Sprint(fl.Field()) + log.Debugf("Validate BGPFilter PrefixLength v6: %s", s) + return s == "*" || bgpFilterPrefixLengthV6.MatchString(s) +} + func validateIgnoredInterface(fl validator.FieldLevel) bool { s := fl.Field().String() log.Debugf("Validate ignored interface name: %s", s) @@ -606,7 +630,7 @@ func ValidateIPv4Network(addr string) error { return fmt.Errorf("Invalid IPv4 network %s", addr) } -// validateIPv4Network validates the field is a valid (strictly masked) IPv6 network. +// validateIPv6Network validates the field is a valid (strictly masked) IPv6 network. // An IP address is valid, and assumed to be fully masked (i.e /128) func validateIPv6Network(fl validator.FieldLevel) bool { n := fl.Field().String() @@ -1395,15 +1419,15 @@ func validateReachableByField(fl validator.FieldLevel) bool { func validateBGPFilterRuleV4(structLevel validator.StructLevel) { fs := structLevel.Current().Interface().(api.BGPFilterRuleV4) - validateBGPFilterRule(structLevel, fs.CIDR, fs.MatchOperator) + validateBGPFilterRule(structLevel, fs.CIDR, fs.MatchOperator, fs.PrefixLength, nil) } func validateBGPFilterRuleV6(structLevel validator.StructLevel) { fs := structLevel.Current().Interface().(api.BGPFilterRuleV6) - validateBGPFilterRule(structLevel, fs.CIDR, fs.MatchOperator) + validateBGPFilterRule(structLevel, fs.CIDR, fs.MatchOperator, nil, fs.PrefixLength) } -func validateBGPFilterRule(structLevel validator.StructLevel, cidr string, op api.BGPFilterMatchOperator) { +func validateBGPFilterRule(structLevel validator.StructLevel, cidr string, op api.BGPFilterMatchOperator, prefixLengthV4 *api.BGPFilterPrefixLengthV4, prefixLengthV6 *api.BGPFilterPrefixLengthV6) { if cidr != "" && op == "" { structLevel.ReportError(cidr, "CIDR", "", reason("MatchOperator cannot be empty when CIDR is not"), "") @@ -1412,6 +1436,14 @@ func validateBGPFilterRule(structLevel validator.StructLevel, cidr string, op ap structLevel.ReportError(op, "MatchOperator", "", reason("CIDR cannot be empty when MatchOperator is not"), "") } + if cidr == "" && prefixLengthV4 != nil { + structLevel.ReportError(prefixLengthV4, "PrefixLength", "", + reason("CIDR cannot be empty when PrefixLength is not"), "") + } + if cidr == "" && prefixLengthV6 != nil { + structLevel.ReportError(prefixLengthV6, "PrefixLength", "", + reason("CIDR cannot be empty when PrefixLength is not"), "") + } } func validateEndpointPort(structLevel validator.StructLevel) { @@ -1496,6 +1528,61 @@ func validateObjectMeta(structLevel validator.StructLevel) { validateObjectMetaLabels(structLevel, om.Labels) } +func validateTier(structLevel validator.StructLevel) { + tier := structLevel.Current().Interface().(api.Tier) + + // Check the name is within the max length. + // Tier names are dependent on the label max length since policy lookup by tier in KDD requires the name to fit in a label. + if len(tier.Name) > k8svalidation.DNS1123LabelMaxLength { + structLevel.ReportError( + reflect.ValueOf(tier.Name), + "Metadata.Name", + "", + reason(fmt.Sprintf("name is too long by %d bytes", len(tier.Name)-k8svalidation.DNS1123LabelMaxLength)), + "", + ) + } + + // Tiers must have simple (no dot) names, since they appear as sub-components of other names. + matched := tierNameRegex.MatchString(tier.Name) + if !matched { + structLevel.ReportError( + reflect.ValueOf(tier.Name), + "Metadata.Name", + "", + reason("name must consist of lower case alphanumeric characters or '-' (regex: "+nameLabelFmt+")"), + "", + ) + } + + if tier.Name == names.DefaultTierName { + if tier.Spec.Order == nil || *tier.Spec.Order != api.DefaultTierOrder { + structLevel.ReportError( + reflect.ValueOf(tier.Spec.Order), + "TierSpec.Order", + "", + reason(fmt.Sprintf("default tier order must be %v", api.DefaultTierOrder)), + "", + ) + } + } + + if tier.Name == names.AdminNetworkPolicyTierName { + if tier.Spec.Order == nil || *tier.Spec.Order != api.AdminNetworkPolicyTierOrder { + structLevel.ReportError( + reflect.ValueOf(tier.Spec.Order), + "TierSpec.Order", + "", + reason(fmt.Sprintf("adminnetworkpolicy tier order must be %v", api.AdminNetworkPolicyTierOrder)), + "", + ) + } + } + + validateObjectMetaAnnotations(structLevel, tier.Annotations) + validateObjectMetaLabels(structLevel, tier.Labels) +} + func validateNetworkPolicy(structLevel validator.StructLevel) { np := structLevel.Current().Interface().(api.NetworkPolicy) spec := np.Spec diff --git a/libcalico-go/lib/validator/v3/validator_test.go b/libcalico-go/lib/validator/v3/validator_test.go index f4d32dd6c0c..c2f399a5076 100644 --- a/libcalico-go/lib/validator/v3/validator_test.go +++ b/libcalico-go/lib/validator/v3/validator_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import ( libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3" "github.com/projectcalico/calico/libcalico-go/lib/backend/encap" + "github.com/projectcalico/calico/libcalico-go/lib/names" v3 "github.com/projectcalico/calico/libcalico-go/lib/validator/v3" ) @@ -42,6 +43,10 @@ func init() { var V256 = 256 var Vffffffff = 0xffffffff var V100000000 = 0x100000000 + var tierOrder = float64(100.0) + var defaultTierOrder = api.DefaultTierOrder + var anpTierOrder = api.AdminNetworkPolicyTierOrder + var defaultTierBadOrder = float64(10.0) // We need pointers to bools, so define the values here. var Vtrue = true @@ -1789,6 +1794,68 @@ func init() { Entry("should accept BGPFilter rule with just an action - 2", api.BGPFilterRuleV6{ Action: "Reject", }, true), + Entry("should accept BGPFilterV4 rule with PrefixLength Min set", api.BGPFilterRuleV4{ + CIDR: "10.0.10.0/24", + MatchOperator: "In", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV4{ + Min: int32Helper(25), + }, + }, true), + Entry("should accept BGPFilterV4 rule with PrefixLength Max set", api.BGPFilterRuleV4{ + CIDR: "10.0.10.0/24", + MatchOperator: "In", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV4{ + Max: int32Helper(30), + }, + }, true), + Entry("should reject BGPFilterV4 rule with PrefixLength Max is out-of-bounds", api.BGPFilterRuleV4{ + CIDR: "10.0.10.0/24", + MatchOperator: "In", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV4{ + Max: int32Helper(64), + }, + }, false), + Entry("should reject BGPFilterV4 rule with PrefixLength populated and CIDR missing", api.BGPFilterRuleV4{ + Interface: "ethx.", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV4{ + Min: int32Helper(16), + }, + }, false), + Entry("should accept BGPFilterV6 rule with PrefixLength Min set", api.BGPFilterRuleV6{ + CIDR: "ffff::/128", + MatchOperator: "In", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV6{ + Min: int32Helper(65), + }, + }, true), + Entry("should accept BGPFilterV6 rule with PrefixLength Max set", api.BGPFilterRuleV6{ + CIDR: "ffff::/128", + MatchOperator: "In", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV6{ + Max: int32Helper(96), + }, + }, true), + Entry("should reject BGPFilterV6 rule with PrefixLength Min is negative", api.BGPFilterRuleV6{ + CIDR: "ffff::/128", + MatchOperator: "In", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV6{ + Min: int32Helper(-16), + }, + }, false), + Entry("should reject BGPFilterV6 rule with PrefixLength populated and CIDR missing", api.BGPFilterRuleV6{ + Interface: "*.calico", + Action: "Reject", + PrefixLength: &api.BGPFilterPrefixLengthV6{ + Min: int32Helper(120), + }, + }, false), // (API) BGPPeerSpec Entry("should accept valid BGPPeerSpec", api.BGPPeerSpec{PeerIP: ipv4_1}, true), @@ -2300,6 +2367,63 @@ func init() { }, true, ), + // Tiers. + Entry("Tier: valid name", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: "foo"}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, true), + Entry("Tier: valid name with dash", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: "fo-o"}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, true), + Entry("Tier: disallow dot in name", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: "fo.o"}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, false), + Entry("Tier: allow valid name of 63 chars", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: string(value63)}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, true), + Entry("Tier: disallow a name of 64 chars", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: string(value64)}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, false), + Entry("Tier: disallow other chars", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: "t~!s.h.i.ng"}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, false), + Entry("Tier: disallow default tier with an invalid order", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: names.DefaultTierName}, + Spec: api.TierSpec{ + Order: &defaultTierBadOrder, + }}, false), + Entry("Tier: allow default tier with the predefined order", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: names.DefaultTierName}, + Spec: api.TierSpec{ + Order: &defaultTierOrder, + }}, true), + Entry("Tier: disallow adminnetworkpolicy tier with an invalid order", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: names.AdminNetworkPolicyTierName}, + Spec: api.TierSpec{ + Order: &defaultTierBadOrder, + }}, false), + Entry("Tier: allow adminnetworkpolicy tier with the predefined order", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: names.AdminNetworkPolicyTierName}, + Spec: api.TierSpec{ + Order: &anpTierOrder, + }}, true), + Entry("Tier: allow a tier with a valid order", &api.Tier{ + ObjectMeta: v1.ObjectMeta{Name: "platform"}, + Spec: api.TierSpec{ + Order: &tierOrder, + }}, true), + // NetworkPolicySpec Types field checks. Entry("allow valid name", &api.NetworkPolicy{ObjectMeta: v1.ObjectMeta{Name: "thing"}}, true), Entry("disallow name with dot", &api.NetworkPolicy{ObjectMeta: v1.ObjectMeta{Name: "t.h.i.ng"}}, false), @@ -3141,3 +3265,7 @@ func mustParsePortRange(min, max uint16) numorstring.Port { } return p } + +func int32Helper(i int32) *int32 { + return &i +} diff --git a/manifests/calico-bpf.yaml b/manifests/calico-bpf.yaml index f0a75683318..6577be141a8 100644 --- a/manifests/calico-bpf.yaml +++ b/manifests/calico-bpf.yaml @@ -334,6 +334,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -355,6 +368,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -376,6 +402,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -397,6 +436,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1208,6 +1260,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1592,6 +1655,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1630,10 +1696,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2671,10 +2761,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2716,6 +2806,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4343,10 +4441,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4384,6 +4482,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4463,6 +4569,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4498,6 +5636,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4609,6 +5748,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4644,6 +5790,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/manifests/calico-policy-only.yaml b/manifests/calico-policy-only.yaml index 0191364fae3..00be5d87e1d 100644 --- a/manifests/calico-policy-only.yaml +++ b/manifests/calico-policy-only.yaml @@ -344,6 +344,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -365,6 +378,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -386,6 +412,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -407,6 +446,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1218,6 +1270,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1602,6 +1665,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1640,10 +1706,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2681,10 +2771,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2726,6 +2816,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4353,10 +4451,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4394,6 +4492,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4473,6 +4579,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4508,6 +5646,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4619,6 +5758,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4654,6 +5800,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/manifests/calico-typha.yaml b/manifests/calico-typha.yaml index b122ea893dd..1c4904c0602 100644 --- a/manifests/calico-typha.yaml +++ b/manifests/calico-typha.yaml @@ -345,6 +345,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -366,6 +379,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -387,6 +413,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -408,6 +447,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1219,6 +1271,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1603,6 +1666,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1641,10 +1707,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2682,10 +2772,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2727,6 +2817,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4354,10 +4452,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4395,6 +4493,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4474,6 +4580,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4509,6 +5647,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4620,6 +5759,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4655,6 +5801,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/manifests/calico-vxlan.yaml b/manifests/calico-vxlan.yaml index 4ff859cee78..83a653f471a 100644 --- a/manifests/calico-vxlan.yaml +++ b/manifests/calico-vxlan.yaml @@ -329,6 +329,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -350,6 +363,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -371,6 +397,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -392,6 +431,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1203,6 +1255,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1587,6 +1650,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1625,10 +1691,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2666,10 +2756,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2711,6 +2801,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4338,10 +4436,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4379,6 +4477,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4458,6 +4564,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4493,6 +5631,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4604,6 +5743,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4639,6 +5785,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/manifests/calico.yaml b/manifests/calico.yaml index 2c372c129e3..6bcd6573130 100644 --- a/manifests/calico.yaml +++ b/manifests/calico.yaml @@ -329,6 +329,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -350,6 +363,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -371,6 +397,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -392,6 +431,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1203,6 +1255,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1587,6 +1650,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1625,10 +1691,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2666,10 +2756,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2711,6 +2801,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4338,10 +4436,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4379,6 +4477,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4458,6 +4564,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4493,6 +5631,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4604,6 +5743,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4639,6 +5785,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/manifests/canal-etcd.yaml b/manifests/canal-etcd.yaml index 2b7ef05e0d7..60fd988cbe0 100644 --- a/manifests/canal-etcd.yaml +++ b/manifests/canal-etcd.yaml @@ -610,7 +610,7 @@ spec: # Runs the flannel daemon to enable vxlan networking between # container hosts. - name: flannel - image: docker.io/flannel/flannel:v0.24.3 + image: docker.io/flannel/flannel:v0.24.4 imagePullPolicy: IfNotPresent env: # The location of the etcd cluster. diff --git a/manifests/canal.yaml b/manifests/canal.yaml index 0c824b32dff..d4da46e5ec9 100644 --- a/manifests/canal.yaml +++ b/manifests/canal.yaml @@ -346,6 +346,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -367,6 +380,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -388,6 +414,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -409,6 +448,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1220,6 +1272,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1604,6 +1667,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1642,10 +1708,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2683,10 +2773,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2728,6 +2818,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4355,10 +4453,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4396,6 +4494,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4475,6 +4581,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4510,6 +5648,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4622,6 +5761,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4657,6 +5803,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list @@ -5031,7 +6178,7 @@ spec: # This container runs flannel using the kube-subnet-mgr backend # for allocating subnets. - name: kube-flannel - image: docker.io/flannel/flannel:v0.24.3 + image: docker.io/flannel/flannel:v0.24.4 imagePullPolicy: IfNotPresent command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr" ] securityContext: diff --git a/manifests/crds.yaml b/manifests/crds.yaml index fdfa5351670..6865bc2f4ca 100644 --- a/manifests/crds.yaml +++ b/manifests/crds.yaml @@ -239,6 +239,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -260,6 +273,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -281,6 +307,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -302,6 +341,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1113,6 +1165,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1497,6 +1560,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1535,10 +1601,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2576,10 +2666,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2621,6 +2711,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4248,10 +4346,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4289,6 +4387,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4367,3 +4473,1035 @@ status: plural: "" conditions: [] storedVersions: [] +--- +# Source: crds/crd.projectcalico.org_tiers.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: crds/policy.networking.k8s.io_adminnetworkpolicies.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/manifests/flannel-migration/calico.yaml b/manifests/flannel-migration/calico.yaml index cebb3dc88a7..62952fff32d 100644 --- a/manifests/flannel-migration/calico.yaml +++ b/manifests/flannel-migration/calico.yaml @@ -329,6 +329,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -350,6 +363,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -371,6 +397,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -392,6 +431,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1203,6 +1255,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1587,6 +1650,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1625,10 +1691,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2666,10 +2756,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2711,6 +2801,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4338,10 +4436,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4379,6 +4477,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4458,6 +4564,1038 @@ status: conditions: [] storedVersions: [] --- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: calico/templates/kdd-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- # Source: calico/templates/calico-kube-controllers-rbac.yaml # Include a clusterrole for the kube-controllers component, # and bind it to the calico-kube-controllers serviceaccount. @@ -4493,6 +5631,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -4604,6 +5743,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -4639,6 +5785,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/manifests/generate.sh b/manifests/generate.sh index 32608b18bbc..0ec839b9494 100755 --- a/manifests/generate.sh +++ b/manifests/generate.sh @@ -14,7 +14,7 @@ CALICO_VERSION=${CALICO_VERSION:-$defaultCalicoVersion} defaultOperatorVersion=$(cat ../charts/tigera-operator/values.yaml | grep version: | cut -d" " -f4) OPERATOR_VERSION=${OPERATOR_VERSION:-$defaultOperatorVersion} -NON_HELM_MANIFEST_IMAGES="calico/apiserver calico/windows calico/ctl calico/csi calico/node-driver-registrar calico/dikastes" +NON_HELM_MANIFEST_IMAGES="calico/apiserver calico/windows calico/ctl calico/csi calico/node-driver-registrar calico/dikastes calico/flannel-migration-controller" echo "Generating manifests for Calico=$CALICO_VERSION and tigera-operator=$OPERATOR_VERSION" diff --git a/manifests/ocp/02-role-tigera-operator.yaml b/manifests/ocp/02-role-tigera-operator.yaml index 75a2489d360..cd4c5e2003d 100644 --- a/manifests/ocp/02-role-tigera-operator.yaml +++ b/manifests/ocp/02-role-tigera-operator.yaml @@ -214,6 +214,12 @@ rules: - watch - create - update + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - delete # Needed for operator lock - apiGroups: - coordination.k8s.io @@ -328,3 +334,38 @@ rules: - update - list - watch + # For tiered network policy actions, tigera-apiserver requires that we authorize the operator for the tier.networkpolicies and tier.globalnetworkpolicies pseudo-kinds. + - apiGroups: + - projectcalico.org + resourceNames: + - allow-tigera.* + resources: + - tier.networkpolicies + - tier.globalnetworkpolicies + verbs: + - list + - watch + - get + - create + - update + - delete + # For tiered network policy actions, tigera-apiserver requires get authorization on the associated tier. + - apiGroups: + - projectcalico.org + resourceNames: + - allow-tigera + resources: + - tiers + verbs: + - get + - delete + - update + # Separated from the above rule since resourceNames does not support the create verb, and requires a field selector for list/watch verbs. + - apiGroups: + - projectcalico.org + resources: + - tiers + verbs: + - create + - list + - watch diff --git a/manifests/ocp/crd.projectcalico.org_bgpfilters.yaml b/manifests/ocp/crd.projectcalico.org_bgpfilters.yaml index 4cac7ae27a0..421273da9c0 100644 --- a/manifests/ocp/crd.projectcalico.org_bgpfilters.yaml +++ b/manifests/ocp/crd.projectcalico.org_bgpfilters.yaml @@ -49,6 +49,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -70,6 +83,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -91,6 +117,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -112,6 +151,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: diff --git a/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml b/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml index d8bbd928373..2990873decd 100644 --- a/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml +++ b/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml @@ -264,6 +264,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -648,6 +659,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -686,10 +700,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, diff --git a/manifests/ocp/crd.projectcalico.org_globalnetworkpolicies.yaml b/manifests/ocp/crd.projectcalico.org_globalnetworkpolicies.yaml index 418cfd05209..f12ae832512 100644 --- a/manifests/ocp/crd.projectcalico.org_globalnetworkpolicies.yaml +++ b/manifests/ocp/crd.projectcalico.org_globalnetworkpolicies.yaml @@ -794,10 +794,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -839,6 +839,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so diff --git a/manifests/ocp/crd.projectcalico.org_networkpolicies.yaml b/manifests/ocp/crd.projectcalico.org_networkpolicies.yaml index 34ac518698e..661cc21cded 100644 --- a/manifests/ocp/crd.projectcalico.org_networkpolicies.yaml +++ b/manifests/ocp/crd.projectcalico.org_networkpolicies.yaml @@ -779,10 +779,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -820,6 +820,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so diff --git a/manifests/ocp/crd.projectcalico.org_tiers.yaml b/manifests/ocp/crd.projectcalico.org_tiers.yaml new file mode 100644 index 00000000000..e905c527194 --- /dev/null +++ b/manifests/ocp/crd.projectcalico.org_tiers.yaml @@ -0,0 +1,63 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + diff --git a/manifests/ocp/operator.tigera.io_apiservers_crd.yaml b/manifests/ocp/operator.tigera.io_apiservers_crd.yaml index e25b4e30c1e..a4b8acbacf4 100644 --- a/manifests/ocp/operator.tigera.io_apiservers_crd.yaml +++ b/manifests/ocp/operator.tigera.io_apiservers_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: apiservers.operator.tigera.io spec: group: operator.tigera.io @@ -16,19 +16,24 @@ spec: - name: v1 schema: openAPIV3Schema: - description: APIServer installs the Tigera API server and related resources. - At most one instance of this resource is supported. It must be named "default" - or "tigera-secure". + description: |- + APIServer installs the Tigera API server and related resources. At most one instance + of this resource is supported. It must be named "default" or "tigera-secure". properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -36,10 +41,10 @@ spec: description: Specification of the desired state for the Tigera API server. properties: apiServerDeployment: - description: APIServerDeployment configures the calico-apiserver (or - tigera-apiserver in Enterprise) Deployment. If used in conjunction - with ControlPlaneNodeSelector or ControlPlaneTolerations, then these - overrides take precedence. + description: |- + APIServerDeployment configures the calico-apiserver (or tigera-apiserver in Enterprise) Deployment. If + used in conjunction with ControlPlaneNodeSelector or ControlPlaneTolerations, then these overrides + take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -48,31 +53,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the API server Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the API server Deployment. If omitted, - the API server Deployment will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -82,65 +85,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the API server Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the API server pods. If specified, this - overrides any affinity that may be set on the API - server Deployment. If omitted, the API server Deployment - will use its default value for affinity. WARNING: - Please note that this field will override the default - API server Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the API server pods. + If specified, this overrides any affinity that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default API server Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -150,9 +144,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -161,27 +154,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -194,9 +177,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -205,27 +187,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -248,31 +220,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -281,27 +250,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -314,9 +273,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -325,27 +283,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -368,21 +316,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -404,10 +347,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -416,24 +357,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -446,30 +378,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -477,10 +399,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -489,24 +409,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -519,51 +430,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -573,28 +469,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -605,11 +495,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -617,23 +505,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -645,39 +526,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -685,23 +556,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -713,41 +577,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -760,21 +612,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -796,10 +643,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -808,24 +653,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -838,30 +674,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -869,10 +695,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -881,24 +705,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -911,51 +726,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -965,28 +765,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -997,11 +791,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1009,23 +801,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1037,39 +822,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1077,23 +852,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1105,41 +873,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -1148,50 +904,44 @@ spec: type: object type: object containers: - description: Containers is a list of API server containers. - If specified, this overrides the specified API server - Deployment containers. If omitted, the API server - Deployment will use its default values for its containers. + description: |- + Containers is a list of API server containers. + If specified, this overrides the specified API server Deployment containers. + If omitted, the API server Deployment will use its default values for its containers. items: description: APIServerDeploymentContainer is an API server Deployment container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment container by name. - Supported values are: calico-apiserver, tigera-queryserver' + description: |- + Name is an enum which identifies the API server Deployment container by name. + Supported values are: calico-apiserver, tigera-queryserver enum: - calico-apiserver - tigera-queryserver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - container's resources. If omitted, the API - server Deployment will use its default value - for this container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment container's resources. + If omitted, the API server Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1208,9 +958,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1219,13 +969,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1233,48 +981,42 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of API server - init containers. If specified, this overrides the - specified API server Deployment init containers. - If omitted, the API server Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of API server init containers. + If specified, this overrides the specified API server Deployment init containers. + If omitted, the API server Deployment will use its default values for its init containers. items: description: APIServerDeploymentInitContainer is an API server Deployment init container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment init container by - name. Supported values are: calico-apiserver-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the API server Deployment init container by name. + Supported values are: calico-apiserver-certs-key-cert-provisioner enum: - calico-apiserver-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - init container's resources. If omitted, the - API server Deployment will use its default - value for this init container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment init container's resources. + If omitted, the API server Deployment will use its default value for this init container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1291,9 +1033,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1302,13 +1044,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1318,88 +1058,72 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the API server pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the API server Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the API server Deployment and each of - this field''s key/value pairs are added to the API - server Deployment nodeSelector provided the key - does not already exist in the object''s nodeSelector. - If omitted, the API server Deployment will use its - default value for nodeSelector. WARNING: Please - note that this field will modify the default API - server Deployment nodeSelector.' + description: |- + NodeSelector is the API server pod's scheduling constraints. + If specified, each of the key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the API server Deployment + and each of this field's key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the API server Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default API server Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the API server pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the API server Deployment. If - omitted, the API server Deployment will use its - default value for tolerations. WARNING: Please note - that this field will override the default API server - Deployment tolerations.' + description: |- + Tolerations is the API server pod's tolerations. + If specified, this overrides any tolerations that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default API server Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -1407,30 +1131,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1442,158 +1161,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -1610,47 +1295,47 @@ spec: description: Most recently observed status for the Tigera API server. properties: conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -1664,11 +1349,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string diff --git a/manifests/ocp/operator.tigera.io_imagesets_crd.yaml b/manifests/ocp/operator.tigera.io_imagesets_crd.yaml index 492ff7092c4..c93aab8e0a2 100644 --- a/manifests/ocp/operator.tigera.io_imagesets_crd.yaml +++ b/manifests/ocp/operator.tigera.io_imagesets_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: imagesets.operator.tigera.io spec: group: operator.tigera.io @@ -16,23 +16,28 @@ spec: - name: v1 schema: openAPIV3Schema: - description: ImageSet is used to specify image digests for the images that - the operator deploys. The name of the ImageSet is expected to be in the - format `-`. The `variant` used is `enterprise` if the - InstallationSpec Variant is `TigeraSecureEnterprise` otherwise it is `calico`. - The `release` must match the version of the variant that the operator is - built to deploy, this version can be obtained by passing the `--version` - flag to the operator binary. + description: |- + ImageSet is used to specify image digests for the images that the operator deploys. + The name of the ImageSet is expected to be in the format `-`. + The `variant` used is `enterprise` if the InstallationSpec Variant is + `TigeraSecureEnterprise` otherwise it is `calico`. + The `release` must match the version of the variant that the operator is built to deploy, + this version can be obtained by passing the `--version` flag to the operator binary. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -40,21 +45,22 @@ spec: description: ImageSetSpec defines the desired state of ImageSet. properties: images: - description: Images is the list of images to use digests. All images - that the operator will deploy must be specified. + description: |- + Images is the list of images to use digests. All images that the operator will deploy + must be specified. items: properties: digest: - description: Digest is the image identifier that will be used - for the Image. The field should not include a leading `@` - and must be prefixed with `sha256:`. + description: |- + Digest is the image identifier that will be used for the Image. + The field should not include a leading `@` and must be prefixed with `sha256:`. type: string image: - description: Image is an image that the operator deploys and - instead of using the built in tag the operator will use the - Digest for the image identifier. The value should be the image - name without registry or tag or digest. For the image `docker.io/calico/node:v3.17.1` - it should be represented as `calico/node` + description: |- + Image is an image that the operator deploys and instead of using the built in tag + the operator will use the Digest for the image identifier. + The value should be the image name without registry or tag or digest. + For the image `docker.io/calico/node:v3.17.1` it should be represented as `calico/node` type: string required: - digest diff --git a/manifests/ocp/operator.tigera.io_installations_crd.yaml b/manifests/ocp/operator.tigera.io_installations_crd.yaml index 9646a41c75a..a4e5120e781 100644 --- a/manifests/ocp/operator.tigera.io_installations_crd.yaml +++ b/manifests/ocp/operator.tigera.io_installations_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: installations.operator.tigera.io spec: group: operator.tigera.io @@ -16,20 +16,25 @@ spec: - name: v1 schema: openAPIV3Schema: - description: Installation configures an installation of Calico or Calico Enterprise. - At most one instance of this resource is supported. It must be named "default". - The Installation API installs core networking and network policy components, - and provides general install-time configuration. + description: |- + Installation configures an installation of Calico or Calico Enterprise. At most one instance + of this resource is supported. It must be named "default". The Installation API installs core networking + and network policy components, and provides general install-time configuration. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -38,9 +43,9 @@ spec: Enterprise installation. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -49,18 +54,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -68,13 +73,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-kube-controllers Deployment. - If omitted, the calico-kube-controllers Deployment will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -84,25 +87,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -110,41 +113,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-kube-controllers pods. If specified, - this overrides any affinity that may be set on the - calico-kube-controllers Deployment. If omitted, - the calico-kube-controllers Deployment will use - its default value for affinity. WARNING: Please - note that this field will override the default calico-kube-controllers - Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -154,9 +147,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -165,27 +157,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -198,9 +180,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -209,27 +190,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -252,31 +223,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -285,27 +253,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -318,9 +276,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -329,27 +286,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -372,21 +319,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -408,10 +350,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -420,24 +360,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -450,30 +381,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -481,10 +402,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -493,24 +412,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -523,51 +433,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -577,28 +472,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -609,11 +498,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -621,23 +508,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -649,39 +529,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -689,23 +559,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -717,41 +580,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -764,21 +615,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -800,10 +646,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -812,24 +656,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -842,30 +677,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -873,10 +698,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -885,24 +708,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -915,51 +729,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -969,28 +768,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -1001,11 +794,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1013,23 +804,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1041,39 +825,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1081,23 +855,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1109,41 +876,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -1152,51 +907,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the specified - calico-kube-controllers Deployment containers. If - omitted, the calico-kube-controllers Deployment - will use its default values for its containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment container - by name. Supported values are: calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment will - use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1213,9 +961,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1224,13 +972,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1240,71 +986,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-kube-controllers - Deployment nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - used in conjunction with ControlPlaneNodeSelector, - that nodeSelector is set on the calico-kube-controllers - Deployment and each of this field''s key/value pairs - are added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-kube-controllers - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -1324,38 +1055,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip forwarding - will be enabled for containers in the CNI configuration. Default: - Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the Calico - CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create if - none exist. At most one IP pool of each address family may be - specified. If omitted, a single pool will be configured if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will be - used for. If not specified or empty, defaults to ["Tunnel", - "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the main - IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -1364,13 +1096,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -1383,15 +1117,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector that - will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -1399,60 +1135,64 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane used - for Linux nodes. In particular, it causes the operator to add - required mounts and environment variables for the particular - dataplane. If not specified, iptables mode is used. Default: - Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods from - running containers until their policy has been programmed in - the dataplane. The specified delay defines the maximum amount - of time that the Calico CNI plugin will wait for policy to be - programmed. \n Only applies to pods created on Linux nodes. - \n * A value of 0 disables pod startup delays. \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to use - on the pod network. If not specified, Calico will perform MTU - auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -1465,30 +1205,32 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -1501,8 +1243,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -1523,21 +1266,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the particular - dataplane. If not specified, it is disabled and the operator - will not render the Calico Windows nodes daemonset. Default: - Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, then - these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -1546,31 +1288,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the calico-node DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node DaemonSet. If omitted, - the calico-node DaemonSet will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -1580,65 +1320,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node pods. If specified, this - overrides any affinity that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -1648,9 +1379,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1659,27 +1389,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1692,9 +1412,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1703,27 +1422,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1746,31 +1455,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1779,27 +1485,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1812,9 +1508,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1823,27 +1518,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1866,21 +1551,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -1902,10 +1582,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1914,24 +1592,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -1944,30 +1613,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -1975,10 +1634,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1987,24 +1644,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2017,51 +1665,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -2071,28 +1704,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -2103,11 +1730,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2115,23 +1740,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2143,39 +1761,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2183,23 +1791,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2211,41 +1812,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -2258,21 +1847,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -2294,10 +1878,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2306,24 +1888,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2336,30 +1909,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -2367,10 +1930,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2379,24 +1940,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2409,51 +1961,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -2463,28 +2000,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -2495,11 +2026,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2507,23 +2036,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2535,39 +2057,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2575,23 +2087,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2603,41 +2108,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -2646,49 +2139,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node containers. - If specified, this overrides the specified calico-node - DaemonSet containers. If omitted, the calico-node - DaemonSet will use its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by name. - Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - container's resources. If omitted, the calico-node - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -2705,9 +2192,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2716,13 +2203,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -2730,21 +2215,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides the - specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use its - default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container by - name. Supported values are: install-cni, hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -2754,33 +2236,27 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - init container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. If used - in conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -2797,9 +2273,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2808,13 +2284,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -2824,65 +2298,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-node DaemonSet - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-node - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use its - default value for tolerations. WARNING: Please note - that this field will override the default calico-node - DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -2901,18 +2363,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -2920,13 +2382,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet will use its - default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -2936,25 +2396,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -2962,40 +2422,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node-windows pods. If specified, - this overrides any affinity that may be set on the - calico-node-windows DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -3005,9 +2456,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3016,27 +2466,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3049,9 +2489,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3060,27 +2499,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3103,31 +2532,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3136,27 +2562,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3169,9 +2585,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3180,27 +2595,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3223,21 +2628,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -3259,10 +2659,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3271,24 +2669,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3301,30 +2690,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -3332,10 +2711,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3344,24 +2721,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3374,51 +2742,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -3428,28 +2781,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -3460,11 +2807,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3472,23 +2817,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3500,39 +2838,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3540,23 +2868,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3568,41 +2889,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -3615,21 +2924,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -3651,10 +2955,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3663,24 +2965,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3693,30 +2986,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -3724,10 +3007,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3736,24 +3017,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3766,51 +3038,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -3820,28 +3077,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -3852,11 +3103,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3864,23 +3113,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3892,39 +3134,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3932,23 +3164,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3960,41 +3185,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -4003,50 +3216,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the specified - calico-node-windows DaemonSet containers. If omitted, - the calico-node-windows DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - container's resources. If omitted, the calico-node-windows - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -4063,9 +3269,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4074,13 +3280,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -4088,21 +3292,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides the - specified calico-node-windows DaemonSet init containers. - If omitted, the calico-node-windows DaemonSet will - use its default values for its init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init container - by name. Supported values are: install-cni;hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -4112,34 +3313,27 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - init container's resources. If omitted, the - calico-node-windows DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -4156,9 +3350,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4167,13 +3361,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -4183,66 +3375,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-node-windows - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-node-windows DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for tolerations. WARNING: - Please note that this field will override the default - calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -4251,9 +3430,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated - and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -4262,18 +3441,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -4281,13 +3460,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-windows-upgrade DaemonSet. - If omitted, the calico-windows-upgrade DaemonSet will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -4297,25 +3474,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -4323,41 +3500,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-windows-upgrade pods. If specified, - this overrides any affinity that may be set on the - calico-windows-upgrade DaemonSet. If omitted, the - calico-windows-upgrade DaemonSet will use its default - value for affinity. WARNING: Please note that this - field will override the default calico-windows-upgrade - DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -4367,9 +3534,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4378,27 +3544,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4411,9 +3567,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4422,27 +3577,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4465,31 +3610,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4498,27 +3640,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4531,9 +3663,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4542,27 +3673,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4585,21 +3706,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -4621,10 +3737,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4633,24 +3747,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4663,30 +3768,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -4694,10 +3789,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4706,24 +3799,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4736,51 +3820,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -4790,28 +3859,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -4822,11 +3885,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -4834,23 +3895,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4862,39 +3916,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -4902,23 +3946,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4930,41 +3967,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -4977,21 +4002,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -5013,10 +4033,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5025,24 +4043,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5055,30 +4064,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -5086,10 +4085,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5098,24 +4095,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5128,51 +4116,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -5182,28 +4155,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -5214,11 +4181,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5226,23 +4191,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5254,39 +4212,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5294,23 +4242,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5322,41 +4263,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -5365,11 +4294,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the specified - calico-windows-upgrade DaemonSet containers. If - omitted, the calico-windows-upgrade DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -5382,32 +4310,26 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5424,9 +4346,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5435,13 +4357,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5451,66 +4371,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-windows-upgrade - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-windows-upgrade DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-windows-upgrade DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -5519,10 +4426,10 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a CertificateSigningRequest - to the certificates.k8s.io/v1beta1 API in order to obtain TLS certificates. - This feature requires that you bring your own CSR signing and approval - process, otherwise pods will be stuck during initialization. + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise + pods will be stuck during initialization. properties: caCert: description: Certificate of the authority that signs the CertificateSigningRequests @@ -5530,9 +4437,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate a - key pair that is associated with the X.509 certificate request. - Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -5543,8 +4450,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature of - the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -5555,9 +4463,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to accommodate - for clusters with multiple signers. Must be formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -5567,21 +4476,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management that - will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For CNI - Plugin Calico, this field defaults to Calico. * For CNI - Plugin GKE, this field defaults to HostLocal. * For CNI - Plugin AzureVNET, this field defaults to AzureVNET. * For - CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only if the - CNI plugin is set to Calico, for all other values of the - CNI plugin the plugin binaries and CNI config is a dependency - that is expected to be installed separately. \n Default: - Calico" + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. + * For CNI Plugin AzureVNET, this field defaults to AzureVNET. + * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -5592,18 +4501,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in the - Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider AKS, - this field defaults to AzureVNET. * For KubernetesProvider EKS, - this field defaults to AmazonVPC. * If aws-node daemonset exists - in kube-system when the Installation resource is created, this - field defaults to AmazonVPC. * For all other cases this field - defaults to Calico. \n For the value Calico, the CNI plugin - binaries and CNI config will be installed as part of deployment, - for all other values the CNI plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -5614,14 +4522,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used to - customize the resource requirements for each component. Node, Typha, - and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config fields - in Installation.Spec instead. The ComponentResource struct associates - a ResourceRequirements with a component by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the component @@ -5635,18 +4543,19 @@ spec: and requests for compute resources such as cpu and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only - be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where this - field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5663,8 +4572,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5673,11 +4583,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5688,55 +4598,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control plane - nodes on which to run Calico components. This is globally applied - to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of the - control plane core components will be deployed. This field applies - to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which are - then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match all - values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to the - value. Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod - can tolerate all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of time - the toleration (which must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. By default, it - is not set, which means tolerate the taint forever (do not - evict). Zero and negative values will be treated as 0 (evict - immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -5751,18 +4660,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -5770,13 +4679,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use its default - value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -5786,65 +4693,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the csi-node-driver DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the csi-node-driver pods. If specified, - this overrides any affinity that may be set on the - csi-node-driver DaemonSet. If omitted, the csi-node-driver - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -5854,9 +4752,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5865,27 +4762,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5898,9 +4785,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5909,27 +4795,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5952,31 +4828,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5985,27 +4858,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6018,9 +4881,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6029,27 +4891,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6072,21 +4924,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6108,10 +4955,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6120,24 +4965,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6150,30 +4986,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6181,10 +5007,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6193,24 +5017,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6223,51 +5038,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6277,28 +5077,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6309,11 +5103,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6321,23 +5113,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6349,39 +5134,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6389,23 +5164,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6417,41 +5185,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -6464,21 +5220,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6500,10 +5251,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6512,24 +5261,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6542,30 +5282,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6573,10 +5303,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6585,24 +5313,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6615,51 +5334,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6669,28 +5373,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6701,11 +5399,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6713,23 +5409,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6741,39 +5430,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6781,23 +5460,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6809,41 +5481,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -6852,48 +5512,44 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the specified - csi-node-driver DaemonSet containers. If omitted, - the csi-node-driver DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container by - name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named csi-node-driver DaemonSet - container's resources. If omitted, the csi-node-driver - DaemonSet will use its default value for this - container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -6910,9 +5566,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -6921,13 +5577,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -6937,66 +5591,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the csi-node-driver - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the csi-node-driver DaemonSet will use - its default value for nodeSelector. WARNING: Please - note that this field will modify the default csi-node-driver - DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use - its default value for tolerations. WARNING: Please - note that this field will override the default csi-node-driver - DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -7005,67 +5646,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are using - FIPS 140-2 validated cryptographic modules and standards. Default: - Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path for - FlexVolume. If not specified, FlexVolume will be enabled by default. - If set to 'None', FlexVolume will be disabled. The default is based - on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to be - specified. If specified then the specified value will be used as - the image path for each image. If not specified or empty, the default - for each image will be used. A special case value, UseDefault, is - supported to explicitly specify the default image path will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image to - be specified. If specified then the given value will be used as - a prefix on each image. If not specified or empty, no prefix will - be used. A special case value, UseDefault, is supported to explicitly - specify the default image prefix will be used for each image. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images to - be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled by default. - If set to ''None'', CSI will be disabled. Default: /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider of - the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to automatically - determine the current provider. If the specified value is not empty, - the Operator will still attempt auto-detection, but will additionally - compare the auto-detected value to the specified value to confirm - they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -7108,68 +5753,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node serves - prometheus metrics on. By default, metrics are not enabled. If specified, - this overrides any FelixConfiguration resources which may exist. - If omitted, then prometheus metrics may still be configured through - FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if type - = "RollingUpdate". --- TODO: Update this to follow our convention - for oneOf, whatever we decide it to be. Same as Deployment `strategy.rollingUpdate`. - See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute number - (ex: 5) or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute number is - calculated from percentage by rounding up to a minimum of - 1. Default value is 0. Example: when this is set to 30%, - at most 30% of the total number of nodes that should be - running the daemon pod (i.e. status.desiredNumberScheduled) - can have their a new pod created before the old pod is marked - as deleted. The update starts by launching new pods on 30% - of nodes. Once an updated pod is available (Ready for at - least minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable for - any reason (Ready transitions to false, is evicted, or is - drained) an updated pod is immediatedly created on that - node without considering surge limits. Allowing surge implies - the possibility that the resources consumed by the daemonset - on any given node can double if the readiness check fails, - and so resource intensive daemonsets should take into account - that they may cause evictions during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that can - be unavailable during the update. Value can be an absolute - number (ex: 5) or a percentage of total number of DaemonSet - pods at the start of the update (ex: 10%). Absolute number - is calculated from percentage by rounding up. This cannot - be 0 if MaxSurge is 0 Default value is 1. Example: when - this is set to 30%, at most 30% of the total number of nodes + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given time. - The update starts by stopping at most 30% of those DaemonSet - pods and then brings up new DaemonSet pods in their place. - Once the new pods are available, it then proceeds onto other - DaemonSet pods, thus ensuring that at least 70% of original - number of DaemonSet pods are available at all times during - the update.' + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -7182,14 +5827,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for component - Docker images. If specified then the given value must end with a - slash character (`/`) and all images will be pulled from this registry. - If not specified then the default registries will be used. A special - case value, UseDefault, is supported to explicitly specify the default - registries will be used. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -7198,24 +5843,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity characteristics - for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with the @@ -7225,30 +5869,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7261,30 +5901,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7306,60 +5942,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity requirements - specified by this field are not met at scheduling time, - the pod will NOT be scheduled onto the node. There is no - fallback to another affinity rules with this setting. This - may cause networking disruption or even catastrophic failure! - PreferredDuringSchedulingIgnoredDuringExecution should be - used for affinity unless there is a specific well understood - reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution is - set by default for AKS nodes, to avoid scheduling Typhas - on virtual-nodes. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7372,30 +6001,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7414,9 +6039,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. If used - in conjunction with the deprecated ComponentResources or TyphaAffinity, - then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -7425,30 +6050,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -7458,45 +6082,43 @@ spec: pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present only - if DeploymentStrategyType = RollingUpdate. to be. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be scheduled above the desired number of pods. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). This can not be 0 if - MaxUnavailable is 0. Absolute number is calculated - from percentage by rounding up. Defaults to 25%. - Example: when this is set to 30%, the new ReplicaSet - can be scaled up immediately when the rolling update - starts, such that the total number of old and new - pods do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be scaled - up further, ensuring that total number of pods running - at any time during the update is at most 130% of - desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of desired - pods (ex: 10%). Absolute number is calculated from - percentage by rounding down. This can not be 0 if - MaxSurge is 0. Defaults to 25%. Example: when this - is set to 30%, the old ReplicaSet can be scaled - down to 70% of desired pods immediately when the - rolling update starts. Once new pods are ready, - old ReplicaSet can be scaled down further, followed - by scaling up the new ReplicaSet, ensuring that - the total number of pods available at all times - during the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -7505,67 +6127,57 @@ spec: will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the typha pods. If specified, this overrides - any affinity that may be set on the typha Deployment. - If omitted, the typha Deployment will use its default - value for affinity. If used in conjunction with - the deprecated TyphaAffinity, then this value takes - precedence. WARNING: Please note that this field - will override the default calico-typha Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -7575,9 +6187,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7586,27 +6197,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7619,9 +6220,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7630,27 +6230,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7673,31 +6263,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7706,27 +6293,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7739,9 +6316,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7750,27 +6326,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7793,21 +6359,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -7829,10 +6390,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7841,24 +6400,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7871,30 +6421,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -7902,10 +6442,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7914,24 +6452,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7944,51 +6473,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -7998,28 +6512,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8030,11 +6538,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8042,23 +6548,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8070,39 +6569,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8110,23 +6599,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8138,41 +6620,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8185,21 +6655,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -8221,10 +6686,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8233,24 +6696,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8263,30 +6717,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -8294,10 +6738,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8306,24 +6748,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8336,51 +6769,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -8390,28 +6808,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8422,11 +6834,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8434,23 +6844,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8462,39 +6865,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8502,23 +6895,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8530,41 +6916,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8573,49 +6947,43 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha Deployment - will use its default values for its containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. Supported - values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment container's - resources. If omitted, the typha Deployment - will use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8632,9 +7000,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8643,13 +7011,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8657,50 +7023,43 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha init - containers. If specified, this overrides the specified - typha Deployment init containers. If omitted, the - typha Deployment will use its default values for - its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by name. - Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment init - container's resources. If omitted, the typha - Deployment will use its default value for - this init container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8717,9 +7076,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8728,13 +7087,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8744,97 +7101,81 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-typha Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-typha - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the pod - needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). If this - value is nil, the default grace period will be used - instead. The grace period is the duration in seconds - after the processes running in the pod are sent - a termination signal and the time when the processes - are forcibly halted with a kill signal. Set this - value longer than the expected cleanup time for - your process. Defaults to 30 seconds. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s tolerations. - If specified, this overrides any tolerations that - may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value - for tolerations. WARNING: Please note that this - field will override the default calico-typha Deployment - tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -8842,30 +7183,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8877,158 +7213,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -9046,8 +7348,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico or - TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -9056,15 +7359,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under [plugins] - [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -9087,18 +7394,19 @@ spec: installation. properties: calicoVersion: - description: CalicoVersion shows the current running version of calico. - CalicoVersion along with Variant is needed to know the exact version - deployed. + description: |- + CalicoVersion shows the current running version of calico. + CalicoVersion along with Variant is needed to know the exact + version deployed. type: string computed: description: Computed is the final installation including overlaid resources. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -9107,19 +7415,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -9127,13 +7434,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -9143,26 +7448,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -9170,43 +7474,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-kube-controllers - pods. If specified, this overrides any affinity - that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -9218,11 +7510,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9230,30 +7520,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9267,11 +7544,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9279,30 +7554,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9325,36 +7587,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9362,30 +7618,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9399,11 +7642,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -9411,30 +7652,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9457,22 +7685,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -9495,12 +7717,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -9509,27 +7728,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9542,33 +7749,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9576,12 +7770,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -9590,27 +7781,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9623,55 +7802,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -9681,30 +7841,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -9717,10 +7869,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9729,24 +7879,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9759,30 +7900,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9790,10 +7921,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9802,24 +7931,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9832,44 +7952,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -9882,22 +7987,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -9920,12 +8019,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -9934,27 +8030,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9967,33 +8051,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -10001,12 +8072,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -10015,27 +8083,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10048,55 +8104,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -10106,30 +8143,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -10142,10 +8171,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10154,24 +8181,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10184,30 +8202,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -10215,10 +8223,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10227,24 +8233,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10257,44 +8254,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -10303,54 +8285,45 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the - specified calico-kube-controllers Deployment - containers. If omitted, the calico-kube-controllers - Deployment will use its default values for its - containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment - container by name. Supported values are: - calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -10366,9 +8339,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -10377,14 +8350,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -10394,76 +8364,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-kube-controllers Deployment nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the calico-kube-controllers Deployment - and each of this field''s key/value pairs are - added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already - exist in the object''s nodeSelector. If omitted, - the calico-kube-controllers Deployment will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the - default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -10483,39 +8433,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip - forwarding will be enabled for containers in the CNI configuration. - Default: Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the - Calico CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create - if none exist. At most one IP pool of each address family - may be specified. If omitted, a single pool will be configured - if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will - be used for. If not specified or empty, defaults - to ["Tunnel", "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the - main IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -10524,14 +8474,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: - IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -10544,15 +8495,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector - that will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -10560,61 +8513,63 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane - used for Linux nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, iptables mode is - used. Default: Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods - from running containers until their policy has been programmed - in the dataplane. The specified delay defines the maximum - amount of time that the Calico CNI plugin will wait for - policy to be programmed. \n Only applies to pods created - on Linux nodes. \n * A value of 0 disables pod startup delays. - \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to - use on the pod network. If not specified, Calico will perform - MTU auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -10628,30 +8583,31 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -10665,8 +8621,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -10688,21 +8645,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, it is disabled and - the operator will not render the Calico Windows nodes daemonset. - Default: Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -10711,19 +8667,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -10731,13 +8686,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -10747,68 +8700,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node pods. If - specified, this overrides any affinity that - may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use - its default value for affinity. WARNING: Please - note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -10820,11 +8761,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10832,30 +8771,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10869,11 +8795,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10881,30 +8805,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10927,36 +8838,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10964,30 +8869,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11001,11 +8893,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -11013,30 +8903,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11059,22 +8936,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -11097,12 +8968,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11111,27 +8979,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11144,33 +9000,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11178,12 +9021,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11192,27 +9032,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11225,55 +9053,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11283,30 +9092,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -11319,10 +9120,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11331,24 +9130,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11361,30 +9151,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11392,10 +9172,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11404,24 +9182,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11434,44 +9203,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11484,22 +9238,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -11522,12 +9270,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11536,27 +9281,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11569,33 +9302,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11603,12 +9323,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11617,27 +9334,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11650,55 +9355,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11708,30 +9394,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -11744,10 +9422,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11756,24 +9432,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11786,30 +9453,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11817,10 +9474,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11829,24 +9484,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11859,44 +9505,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11905,52 +9536,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node - containers. If specified, this overrides the - specified calico-node DaemonSet containers. - If omitted, the calico-node DaemonSet will use - its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by - name. Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -11966,9 +9589,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -11977,14 +9600,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -11992,21 +9612,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides - the specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use - its default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container - by name. Supported values are: install-cni, - hostpath-init, flexvol-driver, mount-bpffs, - node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -12016,35 +9633,28 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - init container's resources. If omitted, - the calico-node DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -12060,9 +9670,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -12071,14 +9681,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -12088,68 +9695,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node DaemonSet - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -12168,19 +9760,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -12188,13 +9779,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -12204,26 +9793,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -12231,42 +9819,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node-windows - pods. If specified, this overrides any affinity - that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the - default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -12278,11 +9855,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12290,30 +9865,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12327,11 +9889,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12339,30 +9899,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12385,36 +9932,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12422,30 +9963,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12459,11 +9987,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12471,30 +9997,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12517,22 +10030,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -12555,12 +10062,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12569,27 +10073,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12602,33 +10094,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12636,12 +10115,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12650,27 +10126,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12683,55 +10147,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -12741,30 +10186,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -12777,10 +10214,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12789,24 +10224,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12819,30 +10245,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12850,10 +10266,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12862,24 +10276,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12892,44 +10297,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -12942,22 +10332,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -12980,12 +10364,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12994,27 +10375,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13027,33 +10396,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13061,12 +10417,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -13075,27 +10428,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13108,55 +10449,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -13166,30 +10488,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -13202,10 +10516,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13214,24 +10526,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13244,30 +10547,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13275,10 +10568,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13287,24 +10578,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13317,44 +10599,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -13363,52 +10630,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the - specified calico-node-windows DaemonSet containers. - If omitted, the calico-node-windows DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet container's resources. If omitted, - the calico-node-windows DaemonSet will - use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -13424,9 +10683,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13435,14 +10694,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13450,23 +10706,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides - the specified calico-node-windows DaemonSet - init containers. If omitted, the calico-node-windows - DaemonSet will use its default values for its - init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init - container by name. Supported values are: - install-cni;hostpath-init, flexvol-driver, - mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -13476,35 +10727,28 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet init container's resources. - If omitted, the calico-node-windows DaemonSet - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -13520,9 +10764,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13531,14 +10775,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13548,68 +10789,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node-windows DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node-windows - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -13618,9 +10844,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is - deprecated and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -13629,19 +10855,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -13649,13 +10874,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -13665,26 +10888,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -13692,43 +10914,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-windows-upgrade - pods. If specified, this overrides any affinity - that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -13740,11 +10950,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13752,30 +10960,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13789,11 +10984,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13801,30 +10994,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13847,36 +11027,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13884,30 +11058,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13921,11 +11082,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -13933,30 +11092,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13979,22 +11125,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -14017,12 +11157,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14031,27 +11168,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14064,33 +11189,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14098,12 +11210,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14112,27 +11221,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14145,55 +11242,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14203,30 +11281,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -14239,10 +11309,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14251,24 +11319,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14281,30 +11340,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14312,10 +11361,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14324,24 +11371,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14354,44 +11392,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14404,22 +11427,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -14442,12 +11459,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14456,27 +11470,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14489,33 +11491,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14523,12 +11512,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14537,27 +11523,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14570,55 +11544,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14628,30 +11583,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -14664,10 +11611,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14676,24 +11621,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14706,30 +11642,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14737,10 +11663,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14749,24 +11673,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14779,44 +11694,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14825,11 +11725,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the - specified calico-windows-upgrade DaemonSet containers. - If omitted, the calico-windows-upgrade DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -14842,33 +11741,27 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -14884,9 +11777,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -14895,14 +11788,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -14912,70 +11802,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-windows-upgrade DaemonSet nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-windows-upgrade DaemonSet - nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -14984,10 +11857,9 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a - CertificateSigningRequest to the certificates.k8s.io/v1beta1 - API in order to obtain TLS certificates. This feature requires - that you bring your own CSR signing and approval process, otherwise + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise pods will be stuck during initialization. properties: caCert: @@ -14996,9 +11868,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate - a key pair that is associated with the X.509 certificate - request. Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -15009,8 +11881,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature - of the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -15021,10 +11894,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to - accommodate for clusters with multiple signers. Must be - formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -15034,21 +11907,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management - that will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For - CNI Plugin Calico, this field defaults to Calico. * - For CNI Plugin GKE, this field defaults to HostLocal. + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. * For CNI Plugin AzureVNET, this field defaults to AzureVNET. * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only - if the CNI plugin is set to Calico, for all other values - of the CNI plugin the plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -15059,18 +11932,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in - the Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider - AKS, this field defaults to AzureVNET. * For KubernetesProvider - EKS, this field defaults to AmazonVPC. * If aws-node daemonset - exists in kube-system when the Installation resource is - created, this field defaults to AmazonVPC. * For all other - cases this field defaults to Calico. \n For the value Calico, - the CNI plugin binaries and CNI config will be installed - as part of deployment, for all other values the CNI plugin - binaries and CNI config is a dependency that is expected - to be installed separately. \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -15081,15 +11953,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used - to customize the resource requirements for each component. Node, - Typha, and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config - fields in Installation.Spec instead. The ComponentResource - struct associates a ResourceRequirements with a component - by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the @@ -15105,19 +11976,20 @@ spec: and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. \n This field - is immutable. It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where - this field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -15134,8 +12006,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -15144,11 +12017,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -15159,56 +12032,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control - plane nodes on which to run Calico components. This is globally - applied to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of - the control plane core components will be deployed. This field - applies to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which - are then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -15223,19 +12094,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15243,13 +12113,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -15259,26 +12127,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15286,42 +12153,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the csi-node-driver pods. - If specified, this overrides any affinity that - may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will - use its default value for affinity. WARNING: - Please note that this field will override the - default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -15333,11 +12189,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15345,30 +12199,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15382,11 +12223,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15394,30 +12233,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15440,36 +12266,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15477,30 +12297,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15514,11 +12321,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15526,30 +12331,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15572,22 +12364,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -15610,12 +12396,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15624,27 +12407,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15657,33 +12428,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15691,12 +12449,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15705,27 +12460,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15738,55 +12481,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -15796,30 +12520,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -15832,10 +12548,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15844,24 +12558,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15874,30 +12579,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15905,10 +12600,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15917,24 +12610,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15947,44 +12631,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -15997,22 +12666,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -16035,12 +12698,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16049,27 +12709,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16082,33 +12730,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16116,12 +12751,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16130,27 +12762,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16163,55 +12783,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -16221,30 +12822,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -16257,10 +12850,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16269,24 +12860,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16299,30 +12881,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16330,10 +12902,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16342,24 +12912,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16372,44 +12933,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -16418,50 +12964,45 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the - specified csi-node-driver DaemonSet containers. - If omitted, the csi-node-driver DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container - by name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named csi-node-driver - DaemonSet container's resources. If omitted, - the csi-node-driver DaemonSet will use - its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -16477,9 +13018,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -16488,14 +13029,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -16505,68 +13043,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - csi-node-driver DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the csi-node-driver - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default csi-node-driver DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -16575,68 +13098,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are - using FIPS 140-2 validated cryptographic modules and standards. - Default: Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path - for FlexVolume. If not specified, FlexVolume will be enabled - by default. If set to 'None', FlexVolume will be disabled. The - default is based on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to - be specified. If specified then the specified value will be - used as the image path for each image. If not specified or empty, - the default for each image will be used. A special case value, - UseDefault, is supported to explicitly specify the default image - path will be used for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image - to be specified. If specified then the given value will be used - as a prefix on each image. If not specified or empty, no prefix - will be used. A special case value, UseDefault, is supported - to explicitly specify the default image prefix will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images - to be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information - to let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled - by default. If set to ''None'', CSI will be disabled. Default: - /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider - of the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to - automatically determine the current provider. If the specified - value is not empty, the Operator will still attempt auto-detection, - but will additionally compare the auto-detected value to the - specified value to confirm they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -16680,71 +13206,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node - serves prometheus metrics on. By default, metrics are not enabled. - If specified, this overrides any FelixConfiguration resources - which may exist. If omitted, then prometheus metrics may still - be configured through FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if - type = "RollingUpdate". --- TODO: Update this to follow - our convention for oneOf, whatever we decide it to be. Same - as Deployment `strategy.rollingUpdate`. See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute - number (ex: 5) or a percentage of desired pods (ex: - 10%). This can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding up - to a minimum of 1. Default value is 0. Example: when - this is set to 30%, at most 30% of the total number - of nodes that should be running the daemon pod (i.e. - status.desiredNumberScheduled) can have their a new - pod created before the old pod is marked as deleted. - The update starts by launching new pods on 30% of nodes. - Once an updated pod is available (Ready for at least - minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable - for any reason (Ready transitions to false, is evicted, - or is drained) an updated pod is immediatedly created - on that node without considering surge limits. Allowing - surge implies the possibility that the resources consumed - by the daemonset on any given node can double if the - readiness check fails, and so resource intensive daemonsets - should take into account that they may cause evictions - during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that - can be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of total number - of DaemonSet pods at the start of the update (ex: 10%). - Absolute number is calculated from percentage by rounding - up. This cannot be 0 if MaxSurge is 0 Default value - is 1. Example: when this is set to 30%, at most 30% - of the total number of nodes that should be running - the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given - time. The update starts by stopping at most 30% of those - DaemonSet pods and then brings up new DaemonSet pods - in their place. Once the new pods are available, it - then proceeds onto other DaemonSet pods, thus ensuring - that at least 70% of original number of DaemonSet pods - are available at all times during the update.' + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -16757,15 +13280,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for - component Docker images. If specified then the given value must - end with a slash character (`/`) and all images will be pulled - from this registry. If not specified then the default registries - will be used. A special case value, UseDefault, is supported - to explicitly specify the default registries will be used. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -16774,24 +13296,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity - characteristics for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -16801,32 +13322,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16839,32 +13354,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16886,63 +13395,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity - requirements specified by this field are not met at - scheduling time, the pod will NOT be scheduled onto - the node. There is no fallback to another affinity rules - with this setting. This may cause networking disruption - or even catastrophic failure! PreferredDuringSchedulingIgnoredDuringExecution - should be used for affinity unless there is a specific - well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution - is set by default for AKS nodes, to avoid scheduling - Typhas on virtual-nodes. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16955,32 +13454,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -16999,9 +13492,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. - If used in conjunction with the deprecated ComponentResources - or TyphaAffinity, then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -17010,32 +13503,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the typha - Deployment. If omitted, the typha Deployment will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -17045,48 +13535,43 @@ spec: existing pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present - only if DeploymentStrategyType = RollingUpdate. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be scheduled above the desired number of - pods. Value can be an absolute number (ex: 5) - or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding - up. Defaults to 25%. Example: when this is set - to 30%, the new ReplicaSet can be scaled up - immediately when the rolling update starts, - such that the total number of old and new pods - do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be - scaled up further, ensuring that total number - of pods running at any time during the update - is at most 130% of desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be unavailable during the update. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). Absolute number is - calculated from percentage by rounding down. - This can not be 0 if MaxSurge is 0. Defaults - to 25%. Example: when this is set to 30%, the - old ReplicaSet can be scaled down to 70% of - desired pods immediately when the rolling update - starts. Once new pods are ready, old ReplicaSet - can be scaled down further, followed by scaling - up the new ReplicaSet, ensuring that the total - number of pods available at all times during - the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -17095,69 +13580,57 @@ spec: that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the typha pods. If specified, - this overrides any affinity that may be set - on the typha Deployment. If omitted, the typha - Deployment will use its default value for affinity. - If used in conjunction with the deprecated TyphaAffinity, - then this value takes precedence. WARNING: Please - note that this field will override the default - calico-typha Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -17169,11 +13642,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17181,30 +13652,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17218,11 +13676,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17230,30 +13686,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17276,36 +13719,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17313,30 +13750,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17350,11 +13774,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17362,30 +13784,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17408,22 +13817,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17446,12 +13849,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17460,27 +13860,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17493,33 +13881,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17527,12 +13902,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17541,27 +13913,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17574,55 +13934,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -17632,30 +13973,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -17668,10 +14001,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17680,24 +14011,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17710,30 +14032,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17741,10 +14053,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17753,24 +14063,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17783,44 +14084,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -17833,22 +14119,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17871,12 +14151,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17885,27 +14162,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17918,33 +14183,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17952,12 +14204,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17966,27 +14215,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17999,55 +14236,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -18057,30 +14275,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -18093,10 +14303,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18105,24 +14313,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18135,30 +14334,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -18166,10 +14355,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18178,24 +14365,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18208,44 +14386,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -18254,52 +14417,44 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha - Deployment will use its default values for its - containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. - Supported values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - container's resources. If omitted, the - typha Deployment will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18315,9 +14470,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18326,14 +14481,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18341,52 +14493,44 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha - init containers. If specified, this overrides - the specified typha Deployment init containers. - If omitted, the typha Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by - name. Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - init container's resources. If omitted, - the typha Deployment will use its default - value for this init container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18402,9 +14546,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18413,14 +14557,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18430,114 +14571,92 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-typha Deployment nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-typha Deployment - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the - pod needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative - integer. The value zero indicates stop immediately - via the kill signal (no opportunity to shut - down). If this value is nil, the default grace - period will be used instead. The grace period - is the duration in seconds after the processes - running in the pod are sent a termination signal - and the time when the processes are forcibly - halted with a kill signal. Set this value longer - than the expected cleanup time for your process. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the typha Deployment. - If omitted, the typha Deployment will use its - default value for tolerations. WARNING: Please - note that this field will override the default - calico-typha Deployment tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes - how a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way - which abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find - matching pods. Pods that match this label - selector are counted to determine the - number of pods in their corresponding - topology domain. + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -18545,20 +14664,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -18570,174 +14685,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of - pod label keys to select the pods over - which spreading will be calculated. The - keys are used to lookup values from the - incoming pod labels, those key-value labels - are ANDed with labelSelector to select - the group of existing pods over which - spreading will be calculated for the incoming - pod. The same key is forbidden to exist - in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the - incoming pod labels will be ignored. A - null or empty list means only match against - labelSelector. \n This is a beta field - and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by - default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree - to which pods may be unevenly distributed. - When `whenUnsatisfiable=DoNotSchedule`, - it is the maximum permitted difference - between the number of matching pods in - the target topology and the global minimum. - The global minimum is the minimum number - of matching pods in an eligible domain - or zero if the number of eligible domains - is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 2/2/1: In this case, the global - minimum is 1. | zone1 | zone2 | zone3 - | | P P | P P | P | - if MaxSkew - is 1, incoming pod can only be scheduled - to zone3 to become 2/2/2; scheduling it - onto zone1(zone2) would make the ActualSkew(3-1) - on zone1(zone2) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled - onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to - topologies that satisfy it. It''s a required - field. Default value is 1 and 0 is not - allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, - and then the calculation of Skew is performed. - And when the number of eligible domains - with matching topology keys equals or - greater than minDomains, this value has - no effect on scheduling. As a result, - when the number of eligible domains is - less than minDomains, scheduler won't - schedule more than maxSkew Pods to those - domains. If value is nil, the constraint - behaves as if MinDomains is equal to 1. - Valid values are integers greater than - 0. When value is not nil, WhenUnsatisfiable - must be DoNotSchedule. \n For example, - in a 3-zone cluster, MaxSkew is set to - 2, MinDomains is set to 5 and pods with - the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P - P | P P | The number of domains is - less than 5(MinDomains), so \"global minimum\" - is treated as 0. In this situation, new - pod with the same labelSelector cannot - be scheduled, because computed skew will - be 3(3 - 0) if new Pod is scheduled to - any of the three zones, it will violate - MaxSkew. \n This is a beta field and requires - the MinDomainsInPodTopologySpread feature - gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates - how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included - in the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in - the calculations. \n If this value is - nil, the behavior is equivalent to the - Honor policy. This is a beta-level feature - default enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates - how we will treat node taints when calculating + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - - Honor: nodes without taints, along with - tainted nodes for which the incoming pod - has a toleration, are included. - Ignore: - node taints are ignored. All nodes are - included. \n If this value is nil, the - behavior is equivalent to the Ignore policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered - to be in the same topology. We consider - each as a "bucket", and try - to put balanced number of pods into each - bucket. We define a domain as a particular - instance of a topology. Also, we define - an eligible domain as a domain whose nodes - meet the requirements of nodeAffinityPolicy - and nodeTaintsPolicy. e.g. If TopologyKey - is "kubernetes.io/hostname", each Node - is a domain of that topology. And, if - TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates - how to deal with a pod if it doesn''t - satisfy the spread constraint. - DoNotSchedule - (default) tells the scheduler not to schedule - it. - ScheduleAnyway tells the scheduler - to schedule the pod in any location, but - giving higher precedence to topologies - that would help reduce the skew. A constraint - is considered "Unsatisfiable" for an incoming - pod if and only if every possible node - assignment for that pod would violate - "MaxSkew" on some topology. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 - | | P P P | P | P | If WhenUnsatisfiable - is set to DoNotSchedule, incoming pod - can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). - In other words, the cluster can still - be imbalanced, but scheduler won''t make - it *more* imbalanced. It''s a required - field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -18755,8 +14820,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico - or TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -18765,15 +14831,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under - [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -18792,47 +14862,47 @@ spec: type: object type: object conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -18846,11 +14916,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -18863,14 +14934,14 @@ spec: type: object type: array imageSet: - description: ImageSet is the name of the ImageSet being used, if there - is an ImageSet that is being used. If an ImageSet is not being used - then this will not be set. + description: |- + ImageSet is the name of the ImageSet being used, if there is an ImageSet + that is being used. If an ImageSet is not being used then this will not be set. type: string mtu: - description: MTU is the most recently observed value for pod network - MTU. This may be an explicitly configured value, or based on Calico's - native auto-detetion. + description: |- + MTU is the most recently observed value for pod network MTU. This may be an explicitly + configured value, or based on Calico's native auto-detetion. format: int32 type: integer variant: diff --git a/manifests/ocp/operator.tigera.io_tigerastatuses_crd.yaml b/manifests/ocp/operator.tigera.io_tigerastatuses_crd.yaml index 2c22726d64d..17a687bd765 100644 --- a/manifests/ocp/operator.tigera.io_tigerastatuses_crd.yaml +++ b/manifests/ocp/operator.tigera.io_tigerastatuses_crd.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: tigerastatuses.operator.tigera.io spec: group: operator.tigera.io @@ -37,14 +37,19 @@ spec: Calico or a Calico Enterprise functional area. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -55,9 +60,9 @@ spec: description: TigeraStatusStatus defines the observed state of TigeraStatus properties: conditions: - description: Conditions represents the latest observed set of conditions - for this component. A component may be one or more of Available, - Progressing, or Degraded. + description: |- + Conditions represents the latest observed set of conditions for this component. A component may be one or more of + Available, Progressing, or Degraded. items: description: TigeraStatusCondition represents a condition attached to a particular component. @@ -72,11 +77,10 @@ spec: context. type: string observedGeneration: - description: observedGeneration represents the generation that - the condition was set based upon. For instance, if generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the generation that the condition was set based upon. + For instance, if generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 type: integer reason: diff --git a/manifests/ocp/policy.networking.k8s.io_adminnetworkpolicies.yaml b/manifests/ocp/policy.networking.k8s.io_adminnetworkpolicies.yaml new file mode 100644 index 00000000000..1e3119f07c3 --- /dev/null +++ b/manifests/ocp/policy.networking.k8s.io_adminnetworkpolicies.yaml @@ -0,0 +1,967 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null + diff --git a/manifests/operator-crds.yaml b/manifests/operator-crds.yaml index 5c806398b54..678a44c1343 100644 --- a/manifests/operator-crds.yaml +++ b/manifests/operator-crds.yaml @@ -5,7 +5,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: apiservers.operator.tigera.io spec: group: operator.tigera.io @@ -19,19 +19,24 @@ spec: - name: v1 schema: openAPIV3Schema: - description: APIServer installs the Tigera API server and related resources. - At most one instance of this resource is supported. It must be named "default" - or "tigera-secure". + description: |- + APIServer installs the Tigera API server and related resources. At most one instance + of this resource is supported. It must be named "default" or "tigera-secure". properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -39,10 +44,10 @@ spec: description: Specification of the desired state for the Tigera API server. properties: apiServerDeployment: - description: APIServerDeployment configures the calico-apiserver (or - tigera-apiserver in Enterprise) Deployment. If used in conjunction - with ControlPlaneNodeSelector or ControlPlaneTolerations, then these - overrides take precedence. + description: |- + APIServerDeployment configures the calico-apiserver (or tigera-apiserver in Enterprise) Deployment. If + used in conjunction with ControlPlaneNodeSelector or ControlPlaneTolerations, then these overrides + take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -51,31 +56,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the API server Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the API server Deployment. If omitted, - the API server Deployment will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -85,65 +88,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the API server Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the API server pods. If specified, this - overrides any affinity that may be set on the API - server Deployment. If omitted, the API server Deployment - will use its default value for affinity. WARNING: - Please note that this field will override the default - API server Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the API server pods. + If specified, this overrides any affinity that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default API server Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -153,9 +147,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -164,27 +157,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -197,9 +180,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -208,27 +190,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -251,31 +223,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -284,27 +253,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -317,9 +276,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -328,27 +286,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -371,21 +319,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -407,10 +350,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -419,24 +360,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -449,30 +381,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -480,10 +402,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -492,24 +412,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -522,51 +433,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -576,28 +472,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -608,11 +498,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -620,23 +508,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -648,39 +529,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -688,23 +559,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -716,41 +580,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -763,21 +615,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -799,10 +646,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -811,24 +656,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -841,30 +677,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -872,10 +698,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -884,24 +708,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -914,51 +729,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -968,28 +768,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -1000,11 +794,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1012,23 +804,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1040,39 +825,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1080,23 +855,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1108,41 +876,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -1151,50 +907,44 @@ spec: type: object type: object containers: - description: Containers is a list of API server containers. - If specified, this overrides the specified API server - Deployment containers. If omitted, the API server - Deployment will use its default values for its containers. + description: |- + Containers is a list of API server containers. + If specified, this overrides the specified API server Deployment containers. + If omitted, the API server Deployment will use its default values for its containers. items: description: APIServerDeploymentContainer is an API server Deployment container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment container by name. - Supported values are: calico-apiserver, tigera-queryserver' + description: |- + Name is an enum which identifies the API server Deployment container by name. + Supported values are: calico-apiserver, tigera-queryserver enum: - calico-apiserver - tigera-queryserver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - container's resources. If omitted, the API - server Deployment will use its default value - for this container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment container's resources. + If omitted, the API server Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1211,9 +961,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1222,13 +972,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1236,48 +984,42 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of API server - init containers. If specified, this overrides the - specified API server Deployment init containers. - If omitted, the API server Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of API server init containers. + If specified, this overrides the specified API server Deployment init containers. + If omitted, the API server Deployment will use its default values for its init containers. items: description: APIServerDeploymentInitContainer is an API server Deployment init container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment init container by - name. Supported values are: calico-apiserver-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the API server Deployment init container by name. + Supported values are: calico-apiserver-certs-key-cert-provisioner enum: - calico-apiserver-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - init container's resources. If omitted, the - API server Deployment will use its default - value for this init container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment init container's resources. + If omitted, the API server Deployment will use its default value for this init container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -1294,9 +1036,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1305,13 +1047,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -1321,88 +1061,72 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the API server pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the API server Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the API server Deployment and each of - this field''s key/value pairs are added to the API - server Deployment nodeSelector provided the key - does not already exist in the object''s nodeSelector. - If omitted, the API server Deployment will use its - default value for nodeSelector. WARNING: Please - note that this field will modify the default API - server Deployment nodeSelector.' + description: |- + NodeSelector is the API server pod's scheduling constraints. + If specified, each of the key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the API server Deployment + and each of this field's key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the API server Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default API server Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the API server pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the API server Deployment. If - omitted, the API server Deployment will use its - default value for tolerations. WARNING: Please note - that this field will override the default API server - Deployment tolerations.' + description: |- + Tolerations is the API server pod's tolerations. + If specified, this overrides any tolerations that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default API server Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -1410,30 +1134,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1445,158 +1164,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -1613,47 +1298,47 @@ spec: description: Most recently observed status for the Tigera API server. properties: conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -1667,11 +1352,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -1698,7 +1384,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: imagesets.operator.tigera.io spec: group: operator.tigera.io @@ -1712,23 +1398,28 @@ spec: - name: v1 schema: openAPIV3Schema: - description: ImageSet is used to specify image digests for the images that - the operator deploys. The name of the ImageSet is expected to be in the - format `-`. The `variant` used is `enterprise` if the - InstallationSpec Variant is `TigeraSecureEnterprise` otherwise it is `calico`. - The `release` must match the version of the variant that the operator is - built to deploy, this version can be obtained by passing the `--version` - flag to the operator binary. + description: |- + ImageSet is used to specify image digests for the images that the operator deploys. + The name of the ImageSet is expected to be in the format `-`. + The `variant` used is `enterprise` if the InstallationSpec Variant is + `TigeraSecureEnterprise` otherwise it is `calico`. + The `release` must match the version of the variant that the operator is built to deploy, + this version can be obtained by passing the `--version` flag to the operator binary. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -1736,21 +1427,22 @@ spec: description: ImageSetSpec defines the desired state of ImageSet. properties: images: - description: Images is the list of images to use digests. All images - that the operator will deploy must be specified. + description: |- + Images is the list of images to use digests. All images that the operator will deploy + must be specified. items: properties: digest: - description: Digest is the image identifier that will be used - for the Image. The field should not include a leading `@` - and must be prefixed with `sha256:`. + description: |- + Digest is the image identifier that will be used for the Image. + The field should not include a leading `@` and must be prefixed with `sha256:`. type: string image: - description: Image is an image that the operator deploys and - instead of using the built in tag the operator will use the - Digest for the image identifier. The value should be the image - name without registry or tag or digest. For the image `docker.io/calico/node:v3.17.1` - it should be represented as `calico/node` + description: |- + Image is an image that the operator deploys and instead of using the built in tag + the operator will use the Digest for the image identifier. + The value should be the image name without registry or tag or digest. + For the image `docker.io/calico/node:v3.17.1` it should be represented as `calico/node` type: string required: - digest @@ -1769,7 +1461,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: installations.operator.tigera.io spec: group: operator.tigera.io @@ -1783,20 +1475,25 @@ spec: - name: v1 schema: openAPIV3Schema: - description: Installation configures an installation of Calico or Calico Enterprise. - At most one instance of this resource is supported. It must be named "default". - The Installation API installs core networking and network policy components, - and provides general install-time configuration. + description: |- + Installation configures an installation of Calico or Calico Enterprise. At most one instance + of this resource is supported. It must be named "default". The Installation API installs core networking + and network policy components, and provides general install-time configuration. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -1805,9 +1502,9 @@ spec: Enterprise installation. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -1816,18 +1513,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -1835,13 +1532,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-kube-controllers Deployment. - If omitted, the calico-kube-controllers Deployment will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -1851,25 +1546,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -1877,41 +1572,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-kube-controllers pods. If specified, - this overrides any affinity that may be set on the - calico-kube-controllers Deployment. If omitted, - the calico-kube-controllers Deployment will use - its default value for affinity. WARNING: Please - note that this field will override the default calico-kube-controllers - Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -1921,9 +1606,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1932,27 +1616,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1965,9 +1639,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -1976,27 +1649,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2019,31 +1682,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2052,27 +1712,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2085,9 +1735,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2096,27 +1745,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2139,21 +1778,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -2175,10 +1809,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2187,24 +1819,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2217,30 +1840,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -2248,10 +1861,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2260,24 +1871,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2290,51 +1892,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -2344,28 +1931,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -2376,11 +1957,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2388,23 +1967,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2416,39 +1988,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2456,23 +2018,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2484,41 +2039,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -2531,21 +2074,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -2567,10 +2105,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2579,24 +2115,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2609,30 +2136,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -2640,10 +2157,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -2652,24 +2167,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -2682,51 +2188,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -2736,28 +2227,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -2768,11 +2253,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2780,23 +2263,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2808,39 +2284,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -2848,23 +2314,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2876,41 +2335,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -2919,51 +2366,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the specified - calico-kube-controllers Deployment containers. If - omitted, the calico-kube-controllers Deployment - will use its default values for its containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment container - by name. Supported values are: calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment will - use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -2980,9 +2420,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2991,13 +2431,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -3007,71 +2445,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-kube-controllers - Deployment nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - used in conjunction with ControlPlaneNodeSelector, - that nodeSelector is set on the calico-kube-controllers - Deployment and each of this field''s key/value pairs - are added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-kube-controllers - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -3091,38 +2514,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip forwarding - will be enabled for containers in the CNI configuration. Default: - Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the Calico - CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create if - none exist. At most one IP pool of each address family may be - specified. If omitted, a single pool will be configured if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will be - used for. If not specified or empty, defaults to ["Tunnel", - "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the main - IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -3131,13 +2555,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -3150,15 +2576,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector that - will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -3166,60 +2594,64 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane used - for Linux nodes. In particular, it causes the operator to add - required mounts and environment variables for the particular - dataplane. If not specified, iptables mode is used. Default: - Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods from - running containers until their policy has been programmed in - the dataplane. The specified delay defines the maximum amount - of time that the Calico CNI plugin will wait for policy to be - programmed. \n Only applies to pods created on Linux nodes. - \n * A value of 0 disables pod startup delays. \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to use - on the pod network. If not specified, Calico will perform MTU - auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -3232,30 +2664,32 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -3268,8 +2702,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -3290,21 +2725,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the particular - dataplane. If not specified, it is disabled and the operator - will not render the Calico Windows nodes daemonset. Default: - Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, then - these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -3313,31 +2747,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the calico-node DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node DaemonSet. If omitted, - the calico-node DaemonSet will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -3347,65 +2779,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node pods. If specified, this - overrides any affinity that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -3415,9 +2838,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3426,27 +2848,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3459,9 +2871,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3470,27 +2881,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3513,31 +2914,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3546,27 +2944,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3579,9 +2967,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3590,27 +2977,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -3633,21 +3010,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -3669,10 +3041,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3681,24 +3051,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3711,30 +3072,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -3742,10 +3093,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -3754,24 +3103,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3784,51 +3124,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -3838,28 +3163,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -3870,11 +3189,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3882,23 +3199,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3910,39 +3220,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -3950,23 +3250,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3978,41 +3271,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -4025,21 +3306,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -4061,10 +3337,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4073,24 +3347,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4103,30 +3368,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -4134,10 +3389,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4146,24 +3399,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4176,51 +3420,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -4230,28 +3459,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -4262,11 +3485,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -4274,23 +3495,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4302,39 +3516,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -4342,23 +3546,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4370,41 +3567,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -4413,49 +3598,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node containers. - If specified, this overrides the specified calico-node - DaemonSet containers. If omitted, the calico-node - DaemonSet will use its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by name. - Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - container's resources. If omitted, the calico-node - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -4472,9 +3651,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4483,13 +3662,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -4497,21 +3674,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides the - specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use its - default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container by - name. Supported values are: install-cni, hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -4521,33 +3695,27 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - init container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. If used - in conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -4564,9 +3732,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4575,13 +3743,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -4591,65 +3757,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-node DaemonSet - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-node - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use its - default value for tolerations. WARNING: Please note - that this field will override the default calico-node - DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -4668,18 +3822,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -4687,13 +3841,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet will use its - default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -4703,25 +3855,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -4729,40 +3881,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node-windows pods. If specified, - this overrides any affinity that may be set on the - calico-node-windows DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -4772,9 +3915,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4783,27 +3925,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4816,9 +3948,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4827,27 +3958,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4870,31 +3991,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4903,27 +4021,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4936,9 +4044,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4947,27 +4054,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4990,21 +4087,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -5026,10 +4118,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5038,24 +4128,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5068,30 +4149,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -5099,10 +4170,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5111,24 +4180,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5141,51 +4201,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -5195,28 +4240,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -5227,11 +4266,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5239,23 +4276,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5267,39 +4297,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5307,23 +4327,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5335,41 +4348,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -5382,21 +4383,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -5418,10 +4414,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5430,24 +4424,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5460,30 +4445,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -5491,10 +4466,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5503,24 +4476,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5533,51 +4497,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -5587,28 +4536,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -5619,11 +4562,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5631,23 +4572,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5659,39 +4593,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5699,23 +4623,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5727,41 +4644,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -5770,50 +4675,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the specified - calico-node-windows DaemonSet containers. If omitted, - the calico-node-windows DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - container's resources. If omitted, the calico-node-windows - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5830,9 +4728,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5841,13 +4739,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5855,21 +4751,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides the - specified calico-node-windows DaemonSet init containers. - If omitted, the calico-node-windows DaemonSet will - use its default values for its init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init container - by name. Supported values are: install-cni;hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -5879,34 +4772,27 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - init container's resources. If omitted, the - calico-node-windows DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5923,9 +4809,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5934,13 +4820,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5950,66 +4834,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-node-windows - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-node-windows DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for tolerations. WARNING: - Please note that this field will override the default - calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -6018,9 +4889,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated - and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -6029,18 +4900,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -6048,13 +4919,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-windows-upgrade DaemonSet. - If omitted, the calico-windows-upgrade DaemonSet will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -6064,25 +4933,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -6090,41 +4959,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-windows-upgrade pods. If specified, - this overrides any affinity that may be set on the - calico-windows-upgrade DaemonSet. If omitted, the - calico-windows-upgrade DaemonSet will use its default - value for affinity. WARNING: Please note that this - field will override the default calico-windows-upgrade - DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -6134,9 +4993,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6145,27 +5003,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6178,9 +5026,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6189,27 +5036,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6232,31 +5069,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6265,27 +5099,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6298,9 +5122,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6309,27 +5132,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6352,21 +5165,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6388,10 +5196,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6400,24 +5206,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6430,30 +5227,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6461,10 +5248,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6473,24 +5258,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6503,51 +5279,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6557,28 +5318,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6589,11 +5344,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6601,23 +5354,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6629,39 +5375,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6669,23 +5405,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6697,41 +5426,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -6744,21 +5461,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6780,10 +5492,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6792,24 +5502,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6822,30 +5523,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6853,10 +5544,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6865,24 +5554,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6895,51 +5575,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6949,28 +5614,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6981,11 +5640,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6993,23 +5650,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7021,39 +5671,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -7061,23 +5701,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7089,41 +5722,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -7132,11 +5753,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the specified - calico-windows-upgrade DaemonSet containers. If - omitted, the calico-windows-upgrade DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -7149,32 +5769,26 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -7191,9 +5805,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7202,13 +5816,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -7218,66 +5830,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-windows-upgrade - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-windows-upgrade DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-windows-upgrade DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -7286,10 +5885,10 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a CertificateSigningRequest - to the certificates.k8s.io/v1beta1 API in order to obtain TLS certificates. - This feature requires that you bring your own CSR signing and approval - process, otherwise pods will be stuck during initialization. + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise + pods will be stuck during initialization. properties: caCert: description: Certificate of the authority that signs the CertificateSigningRequests @@ -7297,9 +5896,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate a - key pair that is associated with the X.509 certificate request. - Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -7310,8 +5909,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature of - the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -7322,9 +5922,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to accommodate - for clusters with multiple signers. Must be formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -7334,21 +5935,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management that - will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For CNI - Plugin Calico, this field defaults to Calico. * For CNI - Plugin GKE, this field defaults to HostLocal. * For CNI - Plugin AzureVNET, this field defaults to AzureVNET. * For - CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only if the - CNI plugin is set to Calico, for all other values of the - CNI plugin the plugin binaries and CNI config is a dependency - that is expected to be installed separately. \n Default: - Calico" + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. + * For CNI Plugin AzureVNET, this field defaults to AzureVNET. + * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -7359,18 +5960,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in the - Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider AKS, - this field defaults to AzureVNET. * For KubernetesProvider EKS, - this field defaults to AmazonVPC. * If aws-node daemonset exists - in kube-system when the Installation resource is created, this - field defaults to AmazonVPC. * For all other cases this field - defaults to Calico. \n For the value Calico, the CNI plugin - binaries and CNI config will be installed as part of deployment, - for all other values the CNI plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -7381,14 +5981,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used to - customize the resource requirements for each component. Node, Typha, - and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config fields - in Installation.Spec instead. The ComponentResource struct associates - a ResourceRequirements with a component by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the component @@ -7402,18 +6002,19 @@ spec: and requests for compute resources such as cpu and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only - be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where this - field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -7430,8 +6031,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7440,11 +6042,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -7455,55 +6057,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control plane - nodes on which to run Calico components. This is globally applied - to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of the - control plane core components will be deployed. This field applies - to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which are - then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match all - values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to the - value. Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod - can tolerate all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of time - the toleration (which must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. By default, it - is not set, which means tolerate the taint forever (do not - evict). Zero and negative values will be treated as 0 (evict - immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -7518,18 +6119,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -7537,13 +6138,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use its default - value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -7553,65 +6152,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the csi-node-driver DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the csi-node-driver pods. If specified, - this overrides any affinity that may be set on the - csi-node-driver DaemonSet. If omitted, the csi-node-driver - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -7621,9 +6211,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7632,27 +6221,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7665,9 +6244,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7676,27 +6254,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7719,31 +6287,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7752,27 +6317,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7785,9 +6340,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7796,27 +6350,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7839,21 +6383,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -7875,10 +6414,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7887,24 +6424,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7917,30 +6445,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -7948,10 +6466,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7960,24 +6476,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7990,51 +6497,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -8044,28 +6536,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8076,11 +6562,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8088,23 +6572,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8116,39 +6593,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8156,23 +6623,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8184,41 +6644,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8231,21 +6679,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -8267,10 +6710,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8279,24 +6720,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8309,30 +6741,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -8340,10 +6762,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8352,24 +6772,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8382,51 +6793,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -8436,28 +6832,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8468,11 +6858,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8480,23 +6868,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8508,39 +6889,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8548,23 +6919,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8576,41 +6940,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8619,48 +6971,44 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the specified - csi-node-driver DaemonSet containers. If omitted, - the csi-node-driver DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container by - name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named csi-node-driver DaemonSet - container's resources. If omitted, the csi-node-driver - DaemonSet will use its default value for this - container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8677,9 +7025,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8688,13 +7036,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8704,66 +7050,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the csi-node-driver - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the csi-node-driver DaemonSet will use - its default value for nodeSelector. WARNING: Please - note that this field will modify the default csi-node-driver - DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use - its default value for tolerations. WARNING: Please - note that this field will override the default csi-node-driver - DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -8772,67 +7105,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are using - FIPS 140-2 validated cryptographic modules and standards. Default: - Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path for - FlexVolume. If not specified, FlexVolume will be enabled by default. - If set to 'None', FlexVolume will be disabled. The default is based - on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to be - specified. If specified then the specified value will be used as - the image path for each image. If not specified or empty, the default - for each image will be used. A special case value, UseDefault, is - supported to explicitly specify the default image path will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image to - be specified. If specified then the given value will be used as - a prefix on each image. If not specified or empty, no prefix will - be used. A special case value, UseDefault, is supported to explicitly - specify the default image prefix will be used for each image. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images to - be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled by default. - If set to ''None'', CSI will be disabled. Default: /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider of - the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to automatically - determine the current provider. If the specified value is not empty, - the Operator will still attempt auto-detection, but will additionally - compare the auto-detected value to the specified value to confirm - they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -8875,68 +7212,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node serves - prometheus metrics on. By default, metrics are not enabled. If specified, - this overrides any FelixConfiguration resources which may exist. - If omitted, then prometheus metrics may still be configured through - FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if type - = "RollingUpdate". --- TODO: Update this to follow our convention - for oneOf, whatever we decide it to be. Same as Deployment `strategy.rollingUpdate`. - See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute number - (ex: 5) or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute number is - calculated from percentage by rounding up to a minimum of - 1. Default value is 0. Example: when this is set to 30%, - at most 30% of the total number of nodes that should be - running the daemon pod (i.e. status.desiredNumberScheduled) - can have their a new pod created before the old pod is marked - as deleted. The update starts by launching new pods on 30% - of nodes. Once an updated pod is available (Ready for at - least minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable for - any reason (Ready transitions to false, is evicted, or is - drained) an updated pod is immediatedly created on that - node without considering surge limits. Allowing surge implies - the possibility that the resources consumed by the daemonset - on any given node can double if the readiness check fails, - and so resource intensive daemonsets should take into account - that they may cause evictions during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that can - be unavailable during the update. Value can be an absolute - number (ex: 5) or a percentage of total number of DaemonSet - pods at the start of the update (ex: 10%). Absolute number - is calculated from percentage by rounding up. This cannot - be 0 if MaxSurge is 0 Default value is 1. Example: when - this is set to 30%, at most 30% of the total number of nodes + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given time. - The update starts by stopping at most 30% of those DaemonSet - pods and then brings up new DaemonSet pods in their place. - Once the new pods are available, it then proceeds onto other - DaemonSet pods, thus ensuring that at least 70% of original - number of DaemonSet pods are available at all times during - the update.' + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -8949,14 +7286,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for component - Docker images. If specified then the given value must end with a - slash character (`/`) and all images will be pulled from this registry. - If not specified then the default registries will be used. A special - case value, UseDefault, is supported to explicitly specify the default - registries will be used. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -8965,24 +7302,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity characteristics - for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with the @@ -8992,30 +7328,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9028,30 +7360,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9073,60 +7401,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity requirements - specified by this field are not met at scheduling time, - the pod will NOT be scheduled onto the node. There is no - fallback to another affinity rules with this setting. This - may cause networking disruption or even catastrophic failure! - PreferredDuringSchedulingIgnoredDuringExecution should be - used for affinity unless there is a specific well understood - reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution is - set by default for AKS nodes, to avoid scheduling Typhas - on virtual-nodes. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9139,30 +7460,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9181,9 +7498,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. If used - in conjunction with the deprecated ComponentResources or TyphaAffinity, - then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -9192,30 +7509,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -9225,45 +7541,43 @@ spec: pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present only - if DeploymentStrategyType = RollingUpdate. to be. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be scheduled above the desired number of pods. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). This can not be 0 if - MaxUnavailable is 0. Absolute number is calculated - from percentage by rounding up. Defaults to 25%. - Example: when this is set to 30%, the new ReplicaSet - can be scaled up immediately when the rolling update - starts, such that the total number of old and new - pods do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be scaled - up further, ensuring that total number of pods running - at any time during the update is at most 130% of - desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of desired - pods (ex: 10%). Absolute number is calculated from - percentage by rounding down. This can not be 0 if - MaxSurge is 0. Defaults to 25%. Example: when this - is set to 30%, the old ReplicaSet can be scaled - down to 70% of desired pods immediately when the - rolling update starts. Once new pods are ready, - old ReplicaSet can be scaled down further, followed - by scaling up the new ReplicaSet, ensuring that - the total number of pods available at all times - during the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -9272,67 +7586,57 @@ spec: will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the typha pods. If specified, this overrides - any affinity that may be set on the typha Deployment. - If omitted, the typha Deployment will use its default - value for affinity. If used in conjunction with - the deprecated TyphaAffinity, then this value takes - precedence. WARNING: Please note that this field - will override the default calico-typha Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -9342,9 +7646,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9353,27 +7656,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9386,9 +7679,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9397,27 +7689,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9440,31 +7722,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9473,27 +7752,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9506,9 +7775,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9517,27 +7785,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9560,21 +7818,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -9596,10 +7849,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9608,24 +7859,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9638,30 +7880,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9669,10 +7901,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9681,24 +7911,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9711,51 +7932,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -9765,28 +7971,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -9797,11 +7997,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -9809,23 +8007,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -9837,39 +8028,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -9877,23 +8058,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -9905,41 +8079,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -9952,21 +8114,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -9988,10 +8145,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10000,24 +8155,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10030,30 +8176,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -10061,10 +8197,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10073,24 +8207,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10103,51 +8228,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -10157,28 +8267,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -10189,11 +8293,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -10201,23 +8303,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -10229,39 +8324,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -10269,23 +8354,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -10297,41 +8375,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -10340,49 +8406,43 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha Deployment - will use its default values for its containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. Supported - values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment container's - resources. If omitted, the typha Deployment - will use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -10399,9 +8459,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -10410,13 +8470,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -10424,50 +8482,43 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha init - containers. If specified, this overrides the specified - typha Deployment init containers. If omitted, the - typha Deployment will use its default values for - its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by name. - Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment init - container's resources. If omitted, the typha - Deployment will use its default value for - this init container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -10484,9 +8535,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -10495,13 +8546,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -10511,97 +8560,81 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-typha Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-typha - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the pod - needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). If this - value is nil, the default grace period will be used - instead. The grace period is the duration in seconds - after the processes running in the pod are sent - a termination signal and the time when the processes - are forcibly halted with a kill signal. Set this - value longer than the expected cleanup time for - your process. Defaults to 30 seconds. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s tolerations. - If specified, this overrides any tolerations that - may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value - for tolerations. WARNING: Please note that this - field will override the default calico-typha Deployment - tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -10609,30 +8642,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -10644,158 +8672,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -10813,8 +8807,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico or - TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -10823,15 +8818,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under [plugins] - [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -10854,18 +8853,19 @@ spec: installation. properties: calicoVersion: - description: CalicoVersion shows the current running version of calico. - CalicoVersion along with Variant is needed to know the exact version - deployed. + description: |- + CalicoVersion shows the current running version of calico. + CalicoVersion along with Variant is needed to know the exact + version deployed. type: string computed: description: Computed is the final installation including overlaid resources. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -10874,19 +8874,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -10894,13 +8893,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -10910,26 +8907,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -10937,43 +8933,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-kube-controllers - pods. If specified, this overrides any affinity - that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -10985,11 +8969,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -10997,30 +8979,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11034,11 +9003,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -11046,30 +9013,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11092,36 +9046,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -11129,30 +9077,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11166,11 +9101,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -11178,30 +9111,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -11224,22 +9144,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -11262,12 +9176,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11276,27 +9187,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11309,33 +9208,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11343,12 +9229,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11357,27 +9240,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11390,55 +9261,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11448,30 +9300,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -11484,10 +9328,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11496,24 +9338,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11526,30 +9359,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11557,10 +9380,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11569,24 +9390,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11599,44 +9411,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11649,22 +9446,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -11687,12 +9478,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11701,27 +9489,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11734,33 +9510,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11768,12 +9531,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -11782,27 +9542,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11815,55 +9563,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11873,30 +9602,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -11909,10 +9630,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11921,24 +9640,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11951,30 +9661,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11982,10 +9682,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11994,24 +9692,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12024,44 +9713,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -12070,54 +9744,45 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the - specified calico-kube-controllers Deployment - containers. If omitted, the calico-kube-controllers - Deployment will use its default values for its - containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment - container by name. Supported values are: - calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -12133,9 +9798,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -12144,14 +9809,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -12161,76 +9823,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-kube-controllers Deployment nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the calico-kube-controllers Deployment - and each of this field''s key/value pairs are - added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already - exist in the object''s nodeSelector. If omitted, - the calico-kube-controllers Deployment will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the - default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -12250,39 +9892,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip - forwarding will be enabled for containers in the CNI configuration. - Default: Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the - Calico CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create - if none exist. At most one IP pool of each address family - may be specified. If omitted, a single pool will be configured - if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will - be used for. If not specified or empty, defaults - to ["Tunnel", "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the - main IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -12291,14 +9933,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: - IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -12311,15 +9954,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector - that will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -12327,61 +9972,63 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane - used for Linux nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, iptables mode is - used. Default: Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods - from running containers until their policy has been programmed - in the dataplane. The specified delay defines the maximum - amount of time that the Calico CNI plugin will wait for - policy to be programmed. \n Only applies to pods created - on Linux nodes. \n * A value of 0 disables pod startup delays. - \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to - use on the pod network. If not specified, Calico will perform - MTU auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -12395,30 +10042,31 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -12432,8 +10080,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -12455,21 +10104,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, it is disabled and - the operator will not render the Calico Windows nodes daemonset. - Default: Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -12478,19 +10126,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -12498,13 +10145,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -12514,68 +10159,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node pods. If - specified, this overrides any affinity that - may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use - its default value for affinity. WARNING: Please - note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -12587,11 +10220,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12599,30 +10230,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12636,11 +10254,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12648,30 +10264,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12694,36 +10297,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12731,30 +10328,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12768,11 +10352,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -12780,30 +10362,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12826,22 +10395,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -12864,12 +10427,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12878,27 +10438,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12911,33 +10459,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12945,12 +10480,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -12959,27 +10491,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12992,55 +10512,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -13050,30 +10551,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -13086,10 +10579,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13098,24 +10589,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13128,30 +10610,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13159,10 +10631,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13171,24 +10641,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13201,44 +10662,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -13251,22 +10697,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -13289,12 +10729,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -13303,27 +10740,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13336,33 +10761,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13370,12 +10782,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -13384,27 +10793,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13417,55 +10814,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -13475,30 +10853,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -13511,10 +10881,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13523,24 +10891,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13553,30 +10912,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -13584,10 +10933,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13596,24 +10943,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -13626,44 +10964,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -13672,52 +10995,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node - containers. If specified, this overrides the - specified calico-node DaemonSet containers. - If omitted, the calico-node DaemonSet will use - its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by - name. Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -13733,9 +11048,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13744,14 +11059,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13759,21 +11071,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides - the specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use - its default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container - by name. Supported values are: install-cni, - hostpath-init, flexvol-driver, mount-bpffs, - node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -13783,35 +11092,28 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - init container's resources. If omitted, - the calico-node DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -13827,9 +11129,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13838,14 +11140,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13855,68 +11154,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node DaemonSet - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -13935,19 +11219,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -13955,13 +11238,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -13971,26 +11252,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -13998,42 +11278,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node-windows - pods. If specified, this overrides any affinity - that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the - default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -14045,11 +11314,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -14057,30 +11324,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -14094,11 +11348,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -14106,30 +11358,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -14152,36 +11391,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -14189,30 +11422,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -14226,11 +11446,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -14238,30 +11456,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -14284,22 +11489,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -14322,12 +11521,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14336,27 +11532,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14369,33 +11553,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14403,12 +11574,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14417,27 +11585,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14450,55 +11606,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14508,30 +11645,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -14544,10 +11673,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14556,24 +11683,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14586,30 +11704,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14617,10 +11725,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14629,24 +11735,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14659,44 +11756,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14709,22 +11791,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -14747,12 +11823,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14761,27 +11834,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14794,33 +11855,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14828,12 +11876,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -14842,27 +11887,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14875,55 +11908,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14933,30 +11947,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -14969,10 +11975,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14981,24 +11985,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15011,30 +12006,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15042,10 +12027,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15054,24 +12037,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15084,44 +12058,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -15130,52 +12089,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the - specified calico-node-windows DaemonSet containers. - If omitted, the calico-node-windows DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet container's resources. If omitted, - the calico-node-windows DaemonSet will - use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -15191,9 +12142,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -15202,14 +12153,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -15217,23 +12165,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides - the specified calico-node-windows DaemonSet - init containers. If omitted, the calico-node-windows - DaemonSet will use its default values for its - init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init - container by name. Supported values are: - install-cni;hostpath-init, flexvol-driver, - mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -15243,35 +12186,28 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet init container's resources. - If omitted, the calico-node-windows DaemonSet - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -15287,9 +12223,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -15298,14 +12234,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -15315,68 +12248,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node-windows DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node-windows - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -15385,9 +12303,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is - deprecated and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -15396,19 +12314,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15416,13 +12333,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -15432,26 +12347,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15459,43 +12373,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-windows-upgrade - pods. If specified, this overrides any affinity - that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -15507,11 +12409,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15519,30 +12419,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15556,11 +12443,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15568,30 +12453,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15614,36 +12486,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15651,30 +12517,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15688,11 +12541,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15700,30 +12551,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15746,22 +12584,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -15784,12 +12616,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15798,27 +12627,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15831,33 +12648,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15865,12 +12669,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15879,27 +12680,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15912,55 +12701,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -15970,30 +12740,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -16006,10 +12768,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16018,24 +12778,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16048,30 +12799,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16079,10 +12820,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16091,24 +12830,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16121,44 +12851,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -16171,22 +12886,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -16209,12 +12918,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16223,27 +12929,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16256,33 +12950,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16290,12 +12971,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16304,27 +12982,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16337,55 +13003,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -16395,30 +13042,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -16431,10 +13070,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16443,24 +13080,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16473,30 +13101,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16504,10 +13122,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16516,24 +13132,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16546,44 +13153,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -16592,11 +13184,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the - specified calico-windows-upgrade DaemonSet containers. - If omitted, the calico-windows-upgrade DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -16609,33 +13200,27 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -16651,9 +13236,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -16662,14 +13247,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -16679,70 +13261,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-windows-upgrade DaemonSet nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-windows-upgrade DaemonSet - nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -16751,10 +13316,9 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a - CertificateSigningRequest to the certificates.k8s.io/v1beta1 - API in order to obtain TLS certificates. This feature requires - that you bring your own CSR signing and approval process, otherwise + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise pods will be stuck during initialization. properties: caCert: @@ -16763,9 +13327,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate - a key pair that is associated with the X.509 certificate - request. Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -16776,8 +13340,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature - of the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -16788,10 +13353,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to - accommodate for clusters with multiple signers. Must be - formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -16801,21 +13366,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management - that will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For - CNI Plugin Calico, this field defaults to Calico. * - For CNI Plugin GKE, this field defaults to HostLocal. + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. * For CNI Plugin AzureVNET, this field defaults to AzureVNET. * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only - if the CNI plugin is set to Calico, for all other values - of the CNI plugin the plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -16826,18 +13391,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in - the Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider - AKS, this field defaults to AzureVNET. * For KubernetesProvider - EKS, this field defaults to AmazonVPC. * If aws-node daemonset - exists in kube-system when the Installation resource is - created, this field defaults to AmazonVPC. * For all other - cases this field defaults to Calico. \n For the value Calico, - the CNI plugin binaries and CNI config will be installed - as part of deployment, for all other values the CNI plugin - binaries and CNI config is a dependency that is expected - to be installed separately. \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -16848,15 +13412,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used - to customize the resource requirements for each component. Node, - Typha, and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config - fields in Installation.Spec instead. The ComponentResource - struct associates a ResourceRequirements with a component - by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the @@ -16872,19 +13435,20 @@ spec: and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. \n This field - is immutable. It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where - this field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -16901,8 +13465,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -16911,11 +13476,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -16926,56 +13491,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control - plane nodes on which to run Calico components. This is globally - applied to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of - the control plane core components will be deployed. This field - applies to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which - are then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -16990,19 +13553,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -17010,13 +13572,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -17026,26 +13586,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -17053,42 +13612,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the csi-node-driver pods. - If specified, this overrides any affinity that - may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will - use its default value for affinity. WARNING: - Please note that this field will override the - default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -17100,11 +13648,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17112,30 +13658,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17149,11 +13682,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17161,30 +13692,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17207,36 +13725,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17244,30 +13756,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17281,11 +13780,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17293,30 +13790,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17339,22 +13823,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17377,12 +13855,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17391,27 +13866,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17424,33 +13887,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17458,12 +13908,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17472,27 +13919,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17505,55 +13940,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -17563,30 +13979,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -17599,10 +14007,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17611,24 +14017,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17641,30 +14038,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17672,10 +14059,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17684,24 +14069,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17714,44 +14090,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -17764,22 +14125,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17802,12 +14157,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17816,27 +14168,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17849,33 +14189,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17883,12 +14210,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17897,27 +14221,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17930,55 +14242,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -17988,30 +14281,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -18024,10 +14309,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18036,24 +14319,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18066,30 +14340,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -18097,10 +14361,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18109,24 +14371,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18139,44 +14392,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -18185,50 +14423,45 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the - specified csi-node-driver DaemonSet containers. - If omitted, the csi-node-driver DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container - by name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named csi-node-driver - DaemonSet container's resources. If omitted, - the csi-node-driver DaemonSet will use - its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18244,9 +14477,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18255,14 +14488,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18272,68 +14502,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - csi-node-driver DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the csi-node-driver - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default csi-node-driver DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -18342,68 +14557,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are - using FIPS 140-2 validated cryptographic modules and standards. - Default: Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path - for FlexVolume. If not specified, FlexVolume will be enabled - by default. If set to 'None', FlexVolume will be disabled. The - default is based on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to - be specified. If specified then the specified value will be - used as the image path for each image. If not specified or empty, - the default for each image will be used. A special case value, - UseDefault, is supported to explicitly specify the default image - path will be used for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image - to be specified. If specified then the given value will be used - as a prefix on each image. If not specified or empty, no prefix - will be used. A special case value, UseDefault, is supported - to explicitly specify the default image prefix will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images - to be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information - to let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled - by default. If set to ''None'', CSI will be disabled. Default: - /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider - of the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to - automatically determine the current provider. If the specified - value is not empty, the Operator will still attempt auto-detection, - but will additionally compare the auto-detected value to the - specified value to confirm they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -18447,71 +14665,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node - serves prometheus metrics on. By default, metrics are not enabled. - If specified, this overrides any FelixConfiguration resources - which may exist. If omitted, then prometheus metrics may still - be configured through FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if - type = "RollingUpdate". --- TODO: Update this to follow - our convention for oneOf, whatever we decide it to be. Same - as Deployment `strategy.rollingUpdate`. See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute - number (ex: 5) or a percentage of desired pods (ex: - 10%). This can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding up - to a minimum of 1. Default value is 0. Example: when - this is set to 30%, at most 30% of the total number - of nodes that should be running the daemon pod (i.e. - status.desiredNumberScheduled) can have their a new - pod created before the old pod is marked as deleted. - The update starts by launching new pods on 30% of nodes. - Once an updated pod is available (Ready for at least - minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable - for any reason (Ready transitions to false, is evicted, - or is drained) an updated pod is immediatedly created - on that node without considering surge limits. Allowing - surge implies the possibility that the resources consumed - by the daemonset on any given node can double if the - readiness check fails, and so resource intensive daemonsets - should take into account that they may cause evictions - during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that - can be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of total number - of DaemonSet pods at the start of the update (ex: 10%). - Absolute number is calculated from percentage by rounding - up. This cannot be 0 if MaxSurge is 0 Default value - is 1. Example: when this is set to 30%, at most 30% - of the total number of nodes that should be running - the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given - time. The update starts by stopping at most 30% of those - DaemonSet pods and then brings up new DaemonSet pods - in their place. Once the new pods are available, it - then proceeds onto other DaemonSet pods, thus ensuring - that at least 70% of original number of DaemonSet pods - are available at all times during the update.' + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -18524,15 +14739,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for - component Docker images. If specified then the given value must - end with a slash character (`/`) and all images will be pulled - from this registry. If not specified then the default registries - will be used. A special case value, UseDefault, is supported - to explicitly specify the default registries will be used. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -18541,24 +14755,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity - characteristics for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -18568,32 +14781,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18606,32 +14813,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18653,63 +14854,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity - requirements specified by this field are not met at - scheduling time, the pod will NOT be scheduled onto - the node. There is no fallback to another affinity rules - with this setting. This may cause networking disruption - or even catastrophic failure! PreferredDuringSchedulingIgnoredDuringExecution - should be used for affinity unless there is a specific - well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution - is set by default for AKS nodes, to avoid scheduling - Typhas on virtual-nodes. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18722,32 +14913,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18766,9 +14951,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. - If used in conjunction with the deprecated ComponentResources - or TyphaAffinity, then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -18777,32 +14962,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the typha - Deployment. If omitted, the typha Deployment will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -18812,48 +14994,43 @@ spec: existing pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present - only if DeploymentStrategyType = RollingUpdate. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be scheduled above the desired number of - pods. Value can be an absolute number (ex: 5) - or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding - up. Defaults to 25%. Example: when this is set - to 30%, the new ReplicaSet can be scaled up - immediately when the rolling update starts, - such that the total number of old and new pods - do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be - scaled up further, ensuring that total number - of pods running at any time during the update - is at most 130% of desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be unavailable during the update. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). Absolute number is - calculated from percentage by rounding down. - This can not be 0 if MaxSurge is 0. Defaults - to 25%. Example: when this is set to 30%, the - old ReplicaSet can be scaled down to 70% of - desired pods immediately when the rolling update - starts. Once new pods are ready, old ReplicaSet - can be scaled down further, followed by scaling - up the new ReplicaSet, ensuring that the total - number of pods available at all times during - the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -18862,69 +15039,57 @@ spec: that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the typha pods. If specified, - this overrides any affinity that may be set - on the typha Deployment. If omitted, the typha - Deployment will use its default value for affinity. - If used in conjunction with the deprecated TyphaAffinity, - then this value takes precedence. WARNING: Please - note that this field will override the default - calico-typha Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -18936,11 +15101,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -18948,30 +15111,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18985,11 +15135,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -18997,30 +15145,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -19043,36 +15178,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -19080,30 +15209,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -19117,11 +15233,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -19129,30 +15243,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -19175,22 +15276,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -19213,12 +15308,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -19227,27 +15319,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19260,33 +15340,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19294,12 +15361,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -19308,27 +15372,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19341,55 +15393,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -19399,30 +15432,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -19435,10 +15460,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19447,24 +15470,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19477,30 +15491,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19508,10 +15512,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19520,24 +15522,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19550,44 +15543,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -19600,22 +15578,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -19638,12 +15610,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -19652,27 +15621,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19685,33 +15642,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19719,12 +15663,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -19733,27 +15674,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19766,55 +15695,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -19824,30 +15734,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -19860,10 +15762,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19872,24 +15772,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19902,30 +15793,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19933,10 +15814,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19945,24 +15824,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19975,44 +15845,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -20021,52 +15876,44 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha - Deployment will use its default values for its - containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. - Supported values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - container's resources. If omitted, the - typha Deployment will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -20082,9 +15929,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -20093,14 +15940,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -20108,52 +15952,44 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha - init containers. If specified, this overrides - the specified typha Deployment init containers. - If omitted, the typha Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by - name. Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - init container's resources. If omitted, - the typha Deployment will use its default - value for this init container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -20169,9 +16005,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -20180,14 +16016,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -20197,114 +16030,92 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-typha Deployment nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-typha Deployment - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the - pod needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative - integer. The value zero indicates stop immediately - via the kill signal (no opportunity to shut - down). If this value is nil, the default grace - period will be used instead. The grace period - is the duration in seconds after the processes - running in the pod are sent a termination signal - and the time when the processes are forcibly - halted with a kill signal. Set this value longer - than the expected cleanup time for your process. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the typha Deployment. - If omitted, the typha Deployment will use its - default value for tolerations. WARNING: Please - note that this field will override the default - calico-typha Deployment tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes - how a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way - which abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find - matching pods. Pods that match this label - selector are counted to determine the - number of pods in their corresponding - topology domain. + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -20312,20 +16123,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -20337,174 +16144,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of - pod label keys to select the pods over - which spreading will be calculated. The - keys are used to lookup values from the - incoming pod labels, those key-value labels - are ANDed with labelSelector to select - the group of existing pods over which - spreading will be calculated for the incoming - pod. The same key is forbidden to exist - in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the - incoming pod labels will be ignored. A - null or empty list means only match against - labelSelector. \n This is a beta field - and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by - default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree - to which pods may be unevenly distributed. - When `whenUnsatisfiable=DoNotSchedule`, - it is the maximum permitted difference - between the number of matching pods in - the target topology and the global minimum. - The global minimum is the minimum number - of matching pods in an eligible domain - or zero if the number of eligible domains - is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 2/2/1: In this case, the global - minimum is 1. | zone1 | zone2 | zone3 - | | P P | P P | P | - if MaxSkew - is 1, incoming pod can only be scheduled - to zone3 to become 2/2/2; scheduling it - onto zone1(zone2) would make the ActualSkew(3-1) - on zone1(zone2) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled - onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to - topologies that satisfy it. It''s a required - field. Default value is 1 and 0 is not - allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, - and then the calculation of Skew is performed. - And when the number of eligible domains - with matching topology keys equals or - greater than minDomains, this value has - no effect on scheduling. As a result, - when the number of eligible domains is - less than minDomains, scheduler won't - schedule more than maxSkew Pods to those - domains. If value is nil, the constraint - behaves as if MinDomains is equal to 1. - Valid values are integers greater than - 0. When value is not nil, WhenUnsatisfiable - must be DoNotSchedule. \n For example, - in a 3-zone cluster, MaxSkew is set to - 2, MinDomains is set to 5 and pods with - the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P - P | P P | The number of domains is - less than 5(MinDomains), so \"global minimum\" - is treated as 0. In this situation, new - pod with the same labelSelector cannot - be scheduled, because computed skew will - be 3(3 - 0) if new Pod is scheduled to - any of the three zones, it will violate - MaxSkew. \n This is a beta field and requires - the MinDomainsInPodTopologySpread feature - gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates - how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included - in the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in - the calculations. \n If this value is - nil, the behavior is equivalent to the - Honor policy. This is a beta-level feature - default enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates - how we will treat node taints when calculating + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - - Honor: nodes without taints, along with - tainted nodes for which the incoming pod - has a toleration, are included. - Ignore: - node taints are ignored. All nodes are - included. \n If this value is nil, the - behavior is equivalent to the Ignore policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered - to be in the same topology. We consider - each as a "bucket", and try - to put balanced number of pods into each - bucket. We define a domain as a particular - instance of a topology. Also, we define - an eligible domain as a domain whose nodes - meet the requirements of nodeAffinityPolicy - and nodeTaintsPolicy. e.g. If TopologyKey - is "kubernetes.io/hostname", each Node - is a domain of that topology. And, if - TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates - how to deal with a pod if it doesn''t - satisfy the spread constraint. - DoNotSchedule - (default) tells the scheduler not to schedule - it. - ScheduleAnyway tells the scheduler - to schedule the pod in any location, but - giving higher precedence to topologies - that would help reduce the skew. A constraint - is considered "Unsatisfiable" for an incoming - pod if and only if every possible node - assignment for that pod would violate - "MaxSkew" on some topology. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 - | | P P P | P | P | If WhenUnsatisfiable - is set to DoNotSchedule, incoming pod - can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). - In other words, the cluster can still - be imbalanced, but scheduler won''t make - it *more* imbalanced. It''s a required - field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -20522,8 +16279,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico - or TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -20532,15 +16290,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under - [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -20559,47 +16321,47 @@ spec: type: object type: object conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -20613,11 +16375,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -20630,14 +16393,14 @@ spec: type: object type: array imageSet: - description: ImageSet is the name of the ImageSet being used, if there - is an ImageSet that is being used. If an ImageSet is not being used - then this will not be set. + description: |- + ImageSet is the name of the ImageSet being used, if there is an ImageSet + that is being used. If an ImageSet is not being used then this will not be set. type: string mtu: - description: MTU is the most recently observed value for pod network - MTU. This may be an explicitly configured value, or based on Calico's - native auto-detetion. + description: |- + MTU is the most recently observed value for pod network MTU. This may be an explicitly + configured value, or based on Calico's native auto-detetion. format: int32 type: integer variant: @@ -20659,7 +16422,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: tigerastatuses.operator.tigera.io spec: group: operator.tigera.io @@ -20694,14 +16457,19 @@ spec: Calico or a Calico Enterprise functional area. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -20712,9 +16480,9 @@ spec: description: TigeraStatusStatus defines the observed state of TigeraStatus properties: conditions: - description: Conditions represents the latest observed set of conditions - for this component. A component may be one or more of Available, - Progressing, or Degraded. + description: |- + Conditions represents the latest observed set of conditions for this component. A component may be one or more of + Available, Progressing, or Degraded. items: description: TigeraStatusCondition represents a condition attached to a particular component. @@ -20729,11 +16497,10 @@ spec: context. type: string observedGeneration: - description: observedGeneration represents the generation that - the condition was set based upon. For instance, if generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the generation that the condition was set based upon. + For instance, if generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 type: integer reason: @@ -21001,6 +16768,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -21022,6 +16802,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -21043,6 +16836,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -21064,6 +16870,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -21875,6 +17694,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -22259,6 +18089,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -22297,10 +18130,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -23338,10 +19195,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -23383,6 +19240,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -25010,10 +20875,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -25051,6 +20916,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -25129,3 +21002,1035 @@ status: plural: "" conditions: [] storedVersions: [] +--- +# Source: crds/crd.projectcalico.org_tiers.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +# Source: crds/policy.networking.k8s.io_adminnetworkpolicies.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/manifests/tigera-operator.yaml b/manifests/tigera-operator.yaml index 041ea640edb..920d6ba139d 100644 --- a/manifests/tigera-operator.yaml +++ b/manifests/tigera-operator.yaml @@ -246,6 +246,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -267,6 +280,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -288,6 +314,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 32 + minimum: 0 + type: integer + min: + format: int32 + maximum: 32 + minimum: 0 + type: integer + type: object source: type: string required: @@ -309,6 +348,19 @@ spec: type: string matchOperator: type: string + prefixLength: + properties: + max: + format: int32 + maximum: 128 + minimum: 0 + type: integer + min: + format: int32 + maximum: 128 + minimum: 0 + type: integer + type: object source: type: string required: @@ -1125,6 +1177,17 @@ spec: information about the BPF policy programs, which can be examined with the calico-bpf command-line tool. type: boolean + bpfRedirectToPeer: + description: 'BPFRedirectToPeer controls which whether it is allowed + to forward straight to the peer side of the workload devices. It + is allowed for any host L2 devices by default (L2Only), but it breaks + TCP dump on the host side of workload device as it bypasses it on + ingress. Value of Enabled also allows redirection from L3 host devices + like IPIP tunnel or Wireguard directly to the peer side of the workload''s + device. This makes redirection faster, however, it breaks tools + like tcpdump on the peer side. Use Enabled with caution. [Default: + L2Only]' + type: string chainInsertMode: description: 'ChainInsertMode controls whether Felix hooks the kernel''s top-level iptables chains by inserting a rule at the top of the @@ -1509,6 +1572,9 @@ spec: pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$ type: string maxIpsetSize: + description: MaxIpsetSize is the maximum number of IP addresses that + can be stored in an IP set. Not applicable if using the nftables + backend. type: integer metadataAddr: description: 'MetadataAddr is the IP address or domain name of the @@ -1547,10 +1613,34 @@ spec: netlinkTimeout: pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$ type: string + nftablesFilterAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesFilterDenyAction: + description: FilterDenyAction controls what happens to traffic that + is denied by network policy. By default Calico blocks traffic with + a "drop" action. If you want to use a "reject" action instead you + can configure it here. + pattern: ^(?i)(Drop|Reject)?$ + type: string + nftablesMangleAllowAction: + pattern: ^(?i)(Accept|Return)?$ + type: string + nftablesMarkMask: + description: 'MarkMask is the mask that Felix selects its nftables + Mark bits from. Should be a 32 bit hexadecimal number with at least + 8 bits set, none of which clash with any other mark bits in use + on the system. [Default: 0xffff0000]' + format: int32 + type: integer nftablesMode: description: 'NFTablesMode configures nftables support in Felix. [Default: Disabled]' type: string + nftablesRefreshInterval: + description: 'NftablesRefreshInterval controls the interval at which + Felix periodically refreshes the nftables rules. [Default: 90s]' + type: string openstackRegion: description: 'OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region Calico/OpenStack deployment, @@ -2589,10 +2679,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -2634,6 +2724,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4270,10 +4368,10 @@ spec: order: description: Order is an optional field that specifies the order in which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". + after those with lower order within the same tier. If the order + is omitted, it may be considered to be "infinite" - i.e. the policy + will be applied last. Policies with identical order will be applied + in alphanumerical order based on the Policy "Name" within the tier. type: number performanceHints: description: "PerformanceHints contains a list of hints to Calico's @@ -4311,6 +4409,14 @@ spec: description: ServiceAccountSelector is an optional field for an expression used to select a pod based on service accounts. type: string + tier: + description: The name of the tier that this policy belongs to. If + this is omitted, the default tier (name is "default") is assumed. The + specified tier must exist in order to create security policies within + the tier, the "default" tier is created automatically if it does + not exist, this means for deployments requiring only a single Tier, + the tier name may be omitted on all policy management requests. + type: string types: description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so @@ -4371,25 +4477,1059 @@ spec: type: string metadata: type: object - spec: - description: NetworkSetSpec contains the specification for a NetworkSet - resource. + spec: + description: NetworkSetSpec contains the specification for a NetworkSet + resource. + properties: + nets: + description: The list of IP networks that belong to this set. + items: + type: string + type: array + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +# Source: crds/calico/crd.projectcalico.org_tiers.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: tiers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: Tier + listKind: TierList + plural: tiers + singular: tier + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TierSpec contains the specification for a security policy + tier resource. + properties: + defaultAction: + description: 'DefaultAction specifies the action applied to workloads + selected by a policy in the tier, but not rule matched the workload''s + traffic. [Default: Deny]' + enum: + - Pass + - Deny + type: string + order: + description: Order is an optional field that specifies the order in + which the tier is applied. Tiers with higher "order" are applied + after those with lower order. If the order is omitted, it may be + considered to be "infinite" - i.e. the tier will be applied last. Tiers + with identical order will be applied in alphanumerical order based + on the Tier "Name". + type: number + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +# Source: crds/calico/policy.networking.k8s.io_adminnetworkpolicies.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30 + policy.networking.k8s.io/bundle-version: v0.1.1 + policy.networking.k8s.io/channel: standard + creationTimestamp: null + name: adminnetworkpolicies.policy.networking.k8s.io +spec: + group: policy.networking.k8s.io + names: + kind: AdminNetworkPolicy + listKind: AdminNetworkPolicyList + plural: adminnetworkpolicies + shortNames: + - anp + singular: adminnetworkpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.priority + name: Priority + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AdminNetworkPolicy is a cluster level resource that is part of the + AdminNetworkPolicy API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of AdminNetworkPolicy. + properties: + egress: + description: |- + Egress is the list of Egress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of egress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the egress rules + would take the highest precedence. + ANPs with no egress rules do not affect egress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressRule describes an action to take on a particular + set of traffic originating from pods selected by a AdminNetworkPolicy's + Subject field. + + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of destination ports for the outgoing egress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + to: + description: |- + To is the List of destinations whose traffic this rule applies to. + If any AdminNetworkPolicyEgressPeer matches the destination of outgoing + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyEgressPeer defines a peer to allow traffic to. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + required: + - action + - to + type: object + maxItems: 100 + type: array + ingress: + description: |- + Ingress is the list of Ingress rules to be applied to the selected pods. + A total of 100 rules will be allowed in each ANP instance. + The relative precedence of ingress rules within a single ANP object (all of + which share the priority) will be determined by the order in which the rule + is written. Thus, a rule that appears at the top of the ingress rules + would take the highest precedence. + ANPs with no ingress rules do not affect ingress traffic. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressRule describes an action to take on a particular + set of traffic destined for pods selected by an AdminNetworkPolicy's + Subject field. + properties: + action: + description: |- + Action specifies the effect this rule will have on matching traffic. + Currently the following actions are supported: + Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy) + Deny: denies the selected traffic + Pass: instructs the selected traffic to skip any remaining ANP rules, and + then pass execution to any NetworkPolicies that select the pod. + If the pod is not selected by any NetworkPolicies then execution + is passed to any BaselineAdminNetworkPolicies that select the pod. + + + Support: Core + enum: + - Allow + - Deny + - Pass + type: string + from: + description: |- + From is the list of sources whose traffic this rule applies to. + If any AdminNetworkPolicyIngressPeer matches the source of incoming + traffic then the specified action is applied. + This field must be defined and contain at least one item. + + + Support: Core + items: + description: |- + AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from. + Exactly one of the selector pointers must be set for a given peer. If a + consumer observes none of its fields are set, they must assume an unknown + option has been specified and fail closed. + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: |- + Namespaces defines a way to select all pods within a set of Namespaces. + Note that host-networked pods are not included in this type of peer. + + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: |- + Pods defines a way to select a set of pods in + a set of namespaces. Note that host-networked pods + are not included in this type of peer. + + + Support: Core + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + maxItems: 100 + minItems: 1 + type: array + name: + description: |- + Name is an identifier for this rule, that may be no more than 100 characters + in length. This field should be used by the implementation to help + improve observability, readability and error-reporting for any applied + AdminNetworkPolicies. + + + Support: Core + maxLength: 100 + type: string + ports: + description: |- + Ports allows for matching traffic based on port and protocols. + This field is a list of ports which should be matched on + the pods selected for this policy i.e the subject of the policy. + So it matches on the destination port for the ingress traffic. + If Ports is not set then the rule does not filter traffic via port. + + + Support: Core + items: + description: |- + AdminNetworkPolicyPort describes how to select network ports on pod(s). + Exactly one field must be set. + maxProperties: 1 + minProperties: 1 + properties: + portNumber: + description: |- + Port selects a port on a pod(s) based on number. + + + Support: Core + properties: + port: + description: |- + Number defines a network port value. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + required: + - port + - protocol + type: object + portRange: + description: |- + PortRange selects a port range on a pod(s) based on provided start and end + values. + + + Support: Core + properties: + end: + description: |- + End defines a network port that is the end of a port range, the End value + must be greater than Start. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + default: TCP + description: |- + Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must + match. If not specified, this field defaults to TCP. + + + Support: Core + type: string + start: + description: |- + Start defines a network port that is the start of a port range, the Start + value must be less than End. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - end + - start + type: object + type: object + maxItems: 100 + type: array + required: + - action + - from + type: object + maxItems: 100 + type: array + priority: + description: |- + Priority is a value from 0 to 1000. Rules with lower priority values have + higher precedence, and are checked before rules with higher priority values. + All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or + BaselineAdminNetworkPolicy rules + The behavior is undefined if two ANP objects have same priority. + + + Support: Core + format: int32 + maximum: 1000 + minimum: 0 + type: integer + subject: + description: |- + Subject defines the pods to which this AdminNetworkPolicy applies. + Note that host-networked pods are not included in subject selection. + + + Support: Core + maxProperties: 1 + minProperties: 1 + properties: + namespaces: + description: Namespaces is used to select pods via namespace selectors. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + pods: + description: Pods is used to select pods via namespace AND pod + selectors. + properties: + namespaceSelector: + description: |- + NamespaceSelector follows standard label selector semantics; if empty, + it selects all Namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + description: |- + PodSelector is used to explicitly select pods within a namespace; if empty, + it selects all Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - namespaceSelector + - podSelector + type: object + type: object + required: + - priority + - subject + type: object + status: + description: Status is the status to be reported by the implementation. properties: - nets: - description: The list of IP networks that belong to this set. + conditions: items: - type: string + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions type: object + required: + - metadata + - spec type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" plural: "" - conditions: [] - storedVersions: [] + conditions: null + storedVersions: null --- # Source: crds/operator.tigera.io_apiservers_crd.yaml @@ -4397,7 +5537,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: apiservers.operator.tigera.io spec: group: operator.tigera.io @@ -4411,19 +5551,24 @@ spec: - name: v1 schema: openAPIV3Schema: - description: APIServer installs the Tigera API server and related resources. - At most one instance of this resource is supported. It must be named "default" - or "tigera-secure". + description: |- + APIServer installs the Tigera API server and related resources. At most one instance + of this resource is supported. It must be named "default" or "tigera-secure". properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -4431,10 +5576,10 @@ spec: description: Specification of the desired state for the Tigera API server. properties: apiServerDeployment: - description: APIServerDeployment configures the calico-apiserver (or - tigera-apiserver in Enterprise) Deployment. If used in conjunction - with ControlPlaneNodeSelector or ControlPlaneTolerations, then these - overrides take precedence. + description: |- + APIServerDeployment configures the calico-apiserver (or tigera-apiserver in Enterprise) Deployment. If + used in conjunction with ControlPlaneNodeSelector or ControlPlaneTolerations, then these overrides + take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -4443,31 +5588,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the API server Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the API server Deployment. If omitted, - the API server Deployment will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -4477,65 +5620,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the API server Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the API server pods. If specified, this - overrides any affinity that may be set on the API - server Deployment. If omitted, the API server Deployment - will use its default value for affinity. WARNING: - Please note that this field will override the default - API server Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the API server pods. + If specified, this overrides any affinity that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default API server Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -4545,9 +5679,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4556,27 +5689,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4589,9 +5712,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4600,27 +5722,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4643,31 +5755,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4676,27 +5785,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4709,9 +5808,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4720,27 +5818,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -4763,21 +5851,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -4799,10 +5882,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4811,24 +5892,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4841,30 +5913,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -4872,10 +5934,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4884,24 +5944,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -4914,51 +5965,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -4968,28 +6004,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -5000,11 +6030,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5012,23 +6040,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5040,39 +6061,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5080,23 +6091,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5108,41 +6112,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -5155,21 +6147,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -5191,10 +6178,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5203,24 +6188,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5233,30 +6209,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -5264,10 +6230,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -5276,24 +6240,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -5306,51 +6261,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -5360,28 +6300,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -5392,11 +6326,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5404,23 +6336,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5432,39 +6357,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5472,23 +6387,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5500,41 +6408,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -5543,50 +6439,44 @@ spec: type: object type: object containers: - description: Containers is a list of API server containers. - If specified, this overrides the specified API server - Deployment containers. If omitted, the API server - Deployment will use its default values for its containers. + description: |- + Containers is a list of API server containers. + If specified, this overrides the specified API server Deployment containers. + If omitted, the API server Deployment will use its default values for its containers. items: description: APIServerDeploymentContainer is an API server Deployment container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment container by name. - Supported values are: calico-apiserver, tigera-queryserver' + description: |- + Name is an enum which identifies the API server Deployment container by name. + Supported values are: calico-apiserver, tigera-queryserver enum: - calico-apiserver - tigera-queryserver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - container's resources. If omitted, the API - server Deployment will use its default value - for this container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment container's resources. + If omitted, the API server Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5603,9 +6493,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5614,13 +6504,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5628,48 +6516,42 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of API server - init containers. If specified, this overrides the - specified API server Deployment init containers. - If omitted, the API server Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of API server init containers. + If specified, this overrides the specified API server Deployment init containers. + If omitted, the API server Deployment will use its default values for its init containers. items: description: APIServerDeploymentInitContainer is an API server Deployment init container. properties: name: - description: 'Name is an enum which identifies - the API server Deployment init container by - name. Supported values are: calico-apiserver-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the API server Deployment init container by name. + Supported values are: calico-apiserver-certs-key-cert-provisioner enum: - calico-apiserver-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named API server Deployment - init container's resources. If omitted, the - API server Deployment will use its default - value for this init container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named API server Deployment init container's resources. + If omitted, the API server Deployment will use its default value for this init container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -5686,9 +6568,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5697,13 +6579,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -5713,88 +6593,72 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the API server pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the API server Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the API server Deployment and each of - this field''s key/value pairs are added to the API - server Deployment nodeSelector provided the key - does not already exist in the object''s nodeSelector. - If omitted, the API server Deployment will use its - default value for nodeSelector. WARNING: Please - note that this field will modify the default API - server Deployment nodeSelector.' + description: |- + NodeSelector is the API server pod's scheduling constraints. + If specified, each of the key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the API server Deployment + and each of this field's key/value pairs are added to the API server Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the API server Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default API server Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the API server pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the API server Deployment. If - omitted, the API server Deployment will use its - default value for tolerations. WARNING: Please note - that this field will override the default API server - Deployment tolerations.' + description: |- + Tolerations is the API server pod's tolerations. + If specified, this overrides any tolerations that may be set on the API server Deployment. + If omitted, the API server Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default API server Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -5802,30 +6666,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5837,158 +6696,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -6005,47 +6830,47 @@ spec: description: Most recently observed status for the Tigera API server. properties: conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -6059,11 +6884,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -6091,7 +6917,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: imagesets.operator.tigera.io spec: group: operator.tigera.io @@ -6105,23 +6931,28 @@ spec: - name: v1 schema: openAPIV3Schema: - description: ImageSet is used to specify image digests for the images that - the operator deploys. The name of the ImageSet is expected to be in the - format `-`. The `variant` used is `enterprise` if the - InstallationSpec Variant is `TigeraSecureEnterprise` otherwise it is `calico`. - The `release` must match the version of the variant that the operator is - built to deploy, this version can be obtained by passing the `--version` - flag to the operator binary. + description: |- + ImageSet is used to specify image digests for the images that the operator deploys. + The name of the ImageSet is expected to be in the format `-`. + The `variant` used is `enterprise` if the InstallationSpec Variant is + `TigeraSecureEnterprise` otherwise it is `calico`. + The `release` must match the version of the variant that the operator is built to deploy, + this version can be obtained by passing the `--version` flag to the operator binary. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -6129,21 +6960,22 @@ spec: description: ImageSetSpec defines the desired state of ImageSet. properties: images: - description: Images is the list of images to use digests. All images - that the operator will deploy must be specified. + description: |- + Images is the list of images to use digests. All images that the operator will deploy + must be specified. items: properties: digest: - description: Digest is the image identifier that will be used - for the Image. The field should not include a leading `@` - and must be prefixed with `sha256:`. + description: |- + Digest is the image identifier that will be used for the Image. + The field should not include a leading `@` and must be prefixed with `sha256:`. type: string image: - description: Image is an image that the operator deploys and - instead of using the built in tag the operator will use the - Digest for the image identifier. The value should be the image - name without registry or tag or digest. For the image `docker.io/calico/node:v3.17.1` - it should be represented as `calico/node` + description: |- + Image is an image that the operator deploys and instead of using the built in tag + the operator will use the Digest for the image identifier. + The value should be the image name without registry or tag or digest. + For the image `docker.io/calico/node:v3.17.1` it should be represented as `calico/node` type: string required: - digest @@ -6163,7 +6995,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: installations.operator.tigera.io spec: group: operator.tigera.io @@ -6177,20 +7009,25 @@ spec: - name: v1 schema: openAPIV3Schema: - description: Installation configures an installation of Calico or Calico Enterprise. - At most one instance of this resource is supported. It must be named "default". - The Installation API installs core networking and network policy components, - and provides general install-time configuration. + description: |- + Installation configures an installation of Calico or Calico Enterprise. At most one instance + of this resource is supported. It must be named "default". The Installation API installs core networking + and network policy components, and provides general install-time configuration. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -6199,9 +7036,9 @@ spec: Enterprise installation. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -6210,18 +7047,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -6229,13 +7066,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-kube-controllers Deployment. - If omitted, the calico-kube-controllers Deployment will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -6245,25 +7080,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -6271,41 +7106,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-kube-controllers pods. If specified, - this overrides any affinity that may be set on the - calico-kube-controllers Deployment. If omitted, - the calico-kube-controllers Deployment will use - its default value for affinity. WARNING: Please - note that this field will override the default calico-kube-controllers - Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -6315,9 +7140,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6326,27 +7150,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6359,9 +7173,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6370,27 +7183,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6413,31 +7216,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6446,27 +7246,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6479,9 +7269,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6490,27 +7279,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -6533,21 +7312,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6569,10 +7343,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6581,24 +7353,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6611,30 +7374,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -6642,10 +7395,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6654,24 +7405,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -6684,51 +7426,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -6738,28 +7465,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -6770,11 +7491,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6782,23 +7501,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6810,39 +7522,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6850,23 +7552,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6878,41 +7573,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -6925,21 +7608,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -6961,10 +7639,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -6973,24 +7649,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7003,30 +7670,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -7034,10 +7691,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7046,24 +7701,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7076,51 +7722,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -7130,28 +7761,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -7162,11 +7787,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -7174,23 +7797,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7202,39 +7818,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -7242,23 +7848,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7270,41 +7869,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -7313,51 +7900,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the specified - calico-kube-controllers Deployment containers. If - omitted, the calico-kube-controllers Deployment - will use its default values for its containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment container - by name. Supported values are: calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment will - use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -7374,9 +7954,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7385,13 +7965,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -7401,71 +7979,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-kube-controllers - Deployment nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - used in conjunction with ControlPlaneNodeSelector, - that nodeSelector is set on the calico-kube-controllers - Deployment and each of this field''s key/value pairs - are added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-kube-controllers - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -7485,38 +8048,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip forwarding - will be enabled for containers in the CNI configuration. Default: - Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the Calico - CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create if - none exist. At most one IP pool of each address family may be - specified. If omitted, a single pool will be configured if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will be - used for. If not specified or empty, defaults to ["Tunnel", - "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the main - IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -7525,13 +8089,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -7544,15 +8110,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector that - will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -7560,60 +8128,64 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane used - for Linux nodes. In particular, it causes the operator to add - required mounts and environment variables for the particular - dataplane. If not specified, iptables mode is used. Default: - Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods from - running containers until their policy has been programmed in - the dataplane. The specified delay defines the maximum amount - of time that the Calico CNI plugin will wait for policy to be - programmed. \n Only applies to pods created on Linux nodes. - \n * A value of 0 disables pod startup delays. \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to use - on the pod network. If not specified, Calico will perform MTU - auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -7626,30 +8198,32 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based on which - source address on the node is used to reach the specified - IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on which - addresses on the nodes are within one of the provided CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching parameters - to select an interface, performing best-effort filtering - based on well-known interface names. + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort + filtering based on well-known interface names. type: boolean interface: description: Interface enables IP auto-detection based on @@ -7662,8 +8236,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -7684,21 +8259,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the particular - dataplane. If not specified, it is disabled and the operator - will not render the Calico Windows nodes daemonset. Default: - Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, then - these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -7707,31 +8281,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the calico-node DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node DaemonSet. If omitted, - the calico-node DaemonSet will use its default value for - minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -7741,65 +8313,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node pods. If specified, this - overrides any affinity that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -7809,9 +8372,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7820,27 +8382,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7853,9 +8405,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7864,27 +8415,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7907,31 +8448,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7940,27 +8478,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7973,9 +8501,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -7984,27 +8511,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -8027,21 +8544,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -8063,10 +8575,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8075,24 +8585,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8105,30 +8606,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -8136,10 +8627,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8148,24 +8637,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8178,51 +8658,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -8232,28 +8697,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8264,11 +8723,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8276,23 +8733,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8304,39 +8754,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8344,23 +8784,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8372,41 +8805,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8419,21 +8840,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -8455,10 +8871,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8467,24 +8881,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8497,30 +8902,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -8528,10 +8923,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -8540,24 +8933,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8570,51 +8954,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -8624,28 +8993,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -8656,11 +9019,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8668,23 +9029,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8696,39 +9050,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -8736,23 +9080,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -8764,41 +9101,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8807,49 +9132,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node containers. - If specified, this overrides the specified calico-node - DaemonSet containers. If omitted, the calico-node - DaemonSet will use its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by name. - Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - container's resources. If omitted, the calico-node - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8866,9 +9185,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8877,13 +9196,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8891,21 +9208,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides the - specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use its - default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container by - name. Supported values are: install-cni, hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -8915,33 +9229,27 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node DaemonSet - init container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. If used - in conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -8958,9 +9266,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -8969,13 +9277,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -8985,65 +9291,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-node DaemonSet - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-node - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use its - default value for tolerations. WARNING: Please note - that this field will override the default calico-node - DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -9062,18 +9356,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -9081,13 +9375,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet will use its - default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -9097,25 +9389,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -9123,40 +9415,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-node-windows pods. If specified, - this overrides any affinity that may be set on the - calico-node-windows DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -9166,9 +9449,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9177,27 +9459,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9210,9 +9482,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9221,27 +9492,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9264,31 +9525,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9297,27 +9555,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9330,9 +9578,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9341,27 +9588,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -9384,21 +9621,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -9420,10 +9652,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9432,24 +9662,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9462,30 +9683,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9493,10 +9704,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9505,24 +9714,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9535,51 +9735,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -9589,28 +9774,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -9621,11 +9800,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -9633,23 +9810,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -9661,39 +9831,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -9701,23 +9861,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -9729,41 +9882,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -9776,21 +9917,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -9812,10 +9948,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9824,24 +9958,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9854,30 +9979,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -9885,10 +10000,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9897,24 +10010,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -9927,51 +10031,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -9981,28 +10070,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -10013,11 +10096,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -10025,23 +10106,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -10053,39 +10127,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -10093,23 +10157,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -10121,41 +10178,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -10164,50 +10209,43 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the specified - calico-node-windows DaemonSet containers. If omitted, - the calico-node-windows DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - container's resources. If omitted, the calico-node-windows - DaemonSet will use its default value for this - container's resources. If used in conjunction - with the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -10224,9 +10262,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -10235,13 +10273,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -10249,21 +10285,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides the - specified calico-node-windows DaemonSet init containers. - If omitted, the calico-node-windows DaemonSet will - use its default values for its init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init container - by name. Supported values are: install-cni;hostpath-init, - flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -10273,34 +10306,27 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-node-windows DaemonSet - init container's resources. If omitted, the - calico-node-windows DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -10317,9 +10343,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -10328,13 +10354,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -10344,66 +10368,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-node-windows - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-node-windows DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for tolerations. WARNING: - Please note that this field will override the default - calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -10412,9 +10423,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated - and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -10423,18 +10434,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -10442,13 +10453,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the calico-windows-upgrade DaemonSet. - If omitted, the calico-windows-upgrade DaemonSet will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -10458,25 +10467,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -10484,41 +10493,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the calico-windows-upgrade pods. If specified, - this overrides any affinity that may be set on the - calico-windows-upgrade DaemonSet. If omitted, the - calico-windows-upgrade DaemonSet will use its default - value for affinity. WARNING: Please note that this - field will override the default calico-windows-upgrade - DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -10528,9 +10527,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10539,27 +10537,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10572,9 +10560,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10583,27 +10570,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10626,31 +10603,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10659,27 +10633,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10692,9 +10656,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10703,27 +10666,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -10746,21 +10699,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -10782,10 +10730,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10794,24 +10740,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10824,30 +10761,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -10855,10 +10782,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -10867,24 +10792,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -10897,51 +10813,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -10951,28 +10852,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -10983,11 +10878,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -10995,23 +10888,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -11023,39 +10909,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -11063,23 +10939,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -11091,41 +10960,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11138,21 +10995,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -11174,10 +11026,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11186,24 +11036,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11216,30 +11057,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -11247,10 +11078,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -11259,24 +11088,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -11289,51 +11109,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -11343,28 +11148,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -11375,11 +11174,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -11387,23 +11184,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -11415,39 +11205,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -11455,23 +11235,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -11483,41 +11256,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -11526,11 +11287,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the specified - calico-windows-upgrade DaemonSet containers. If - omitted, the calico-windows-upgrade DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -11543,32 +11303,26 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -11585,9 +11339,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -11596,13 +11350,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -11612,66 +11364,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the calico-windows-upgrade - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the calico-windows-upgrade DaemonSet will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the default - calico-windows-upgrade DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -11680,10 +11419,10 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a CertificateSigningRequest - to the certificates.k8s.io/v1beta1 API in order to obtain TLS certificates. - This feature requires that you bring your own CSR signing and approval - process, otherwise pods will be stuck during initialization. + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise + pods will be stuck during initialization. properties: caCert: description: Certificate of the authority that signs the CertificateSigningRequests @@ -11691,9 +11430,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate a - key pair that is associated with the X.509 certificate request. - Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -11704,8 +11443,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature of - the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -11716,9 +11456,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to accommodate - for clusters with multiple signers. Must be formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -11728,21 +11469,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management that - will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For CNI - Plugin Calico, this field defaults to Calico. * For CNI - Plugin GKE, this field defaults to HostLocal. * For CNI - Plugin AzureVNET, this field defaults to AzureVNET. * For - CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only if the - CNI plugin is set to Calico, for all other values of the - CNI plugin the plugin binaries and CNI config is a dependency - that is expected to be installed separately. \n Default: - Calico" + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. + * For CNI Plugin AzureVNET, this field defaults to AzureVNET. + * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -11753,18 +11494,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in the - Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider AKS, - this field defaults to AzureVNET. * For KubernetesProvider EKS, - this field defaults to AmazonVPC. * If aws-node daemonset exists - in kube-system when the Installation resource is created, this - field defaults to AmazonVPC. * For all other cases this field - defaults to Calico. \n For the value Calico, the CNI plugin - binaries and CNI config will be installed as part of deployment, - for all other values the CNI plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -11775,14 +11515,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used to - customize the resource requirements for each component. Node, Typha, - and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config fields - in Installation.Spec instead. The ComponentResource struct associates - a ResourceRequirements with a component by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the component @@ -11796,18 +11536,19 @@ spec: and requests for compute resources such as cpu and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only - be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where this - field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -11824,8 +11565,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -11834,11 +11576,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -11849,55 +11591,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control plane - nodes on which to run Calico components. This is globally applied - to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of the - control plane core components will be deployed. This field applies - to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which are - then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match all - values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to the - value. Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod - can tolerate all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of time - the toleration (which must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. By default, it - is not set, which means tolerate the taint forever (do not - evict). Zero and negative values will be treated as 0 (evict - immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -11912,18 +11653,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -11931,13 +11672,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created DaemonSet pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use its default - value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -11947,65 +11686,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the csi-node-driver DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the csi-node-driver pods. If specified, - this overrides any affinity that may be set on the - csi-node-driver DaemonSet. If omitted, the csi-node-driver - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -12015,9 +11745,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12026,27 +11755,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12059,9 +11778,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12070,27 +11788,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12113,31 +11821,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12146,27 +11851,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12179,9 +11874,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12190,27 +11884,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -12233,21 +11917,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -12269,10 +11948,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12281,24 +11958,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12311,30 +11979,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12342,10 +12000,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12354,24 +12010,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12384,51 +12031,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -12438,28 +12070,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -12470,11 +12096,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -12482,23 +12106,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -12510,39 +12127,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -12550,23 +12157,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -12578,41 +12178,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -12625,21 +12213,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -12661,10 +12244,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12673,24 +12254,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12703,30 +12275,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -12734,10 +12296,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -12746,24 +12306,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -12776,51 +12327,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -12830,28 +12366,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -12862,11 +12392,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -12874,23 +12402,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -12902,39 +12423,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -12942,23 +12453,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -12970,41 +12474,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -13013,48 +12505,44 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the specified - csi-node-driver DaemonSet containers. If omitted, - the csi-node-driver DaemonSet will use its default - values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container by - name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named csi-node-driver DaemonSet - container's resources. If omitted, the csi-node-driver - DaemonSet will use its default value for this - container's resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -13071,9 +12559,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -13082,13 +12570,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -13098,66 +12584,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, each - of the key/value pairs are added to the csi-node-driver - DaemonSet nodeSelector provided the key does not - already exist in the object''s nodeSelector. If - omitted, the csi-node-driver DaemonSet will use - its default value for nodeSelector. WARNING: Please - note that this field will modify the default csi-node-driver - DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver pod''s - tolerations. If specified, this overrides any tolerations - that may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will use - its default value for tolerations. WARNING: Please - note that this field will override the default csi-node-driver - DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -13166,67 +12639,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are using - FIPS 140-2 validated cryptographic modules and standards. Default: - Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path for - FlexVolume. If not specified, FlexVolume will be enabled by default. - If set to 'None', FlexVolume will be disabled. The default is based - on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to be - specified. If specified then the specified value will be used as - the image path for each image. If not specified or empty, the default - for each image will be used. A special case value, UseDefault, is - supported to explicitly specify the default image path will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image to - be specified. If specified then the given value will be used as - a prefix on each image. If not specified or empty, no prefix will - be used. A special case value, UseDefault, is supported to explicitly - specify the default image prefix will be used for each image. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images to - be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled by default. - If set to ''None'', CSI will be disabled. Default: /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider of - the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to automatically - determine the current provider. If the specified value is not empty, - the Operator will still attempt auto-detection, but will additionally - compare the auto-detected value to the specified value to confirm - they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -13269,68 +12746,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node serves - prometheus metrics on. By default, metrics are not enabled. If specified, - this overrides any FelixConfiguration resources which may exist. - If omitted, then prometheus metrics may still be configured through - FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if type - = "RollingUpdate". --- TODO: Update this to follow our convention - for oneOf, whatever we decide it to be. Same as Deployment `strategy.rollingUpdate`. - See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute number - (ex: 5) or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute number is - calculated from percentage by rounding up to a minimum of - 1. Default value is 0. Example: when this is set to 30%, - at most 30% of the total number of nodes that should be - running the daemon pod (i.e. status.desiredNumberScheduled) - can have their a new pod created before the old pod is marked - as deleted. The update starts by launching new pods on 30% - of nodes. Once an updated pod is available (Ready for at - least minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable for - any reason (Ready transitions to false, is evicted, or is - drained) an updated pod is immediatedly created on that - node without considering surge limits. Allowing surge implies - the possibility that the resources consumed by the daemonset - on any given node can double if the readiness check fails, - and so resource intensive daemonsets should take into account - that they may cause evictions during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that can - be unavailable during the update. Value can be an absolute - number (ex: 5) or a percentage of total number of DaemonSet - pods at the start of the update (ex: 10%). Absolute number - is calculated from percentage by rounding up. This cannot - be 0 if MaxSurge is 0 Default value is 1. Example: when - this is set to 30%, at most 30% of the total number of nodes + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given time. - The update starts by stopping at most 30% of those DaemonSet - pods and then brings up new DaemonSet pods in their place. - Once the new pods are available, it then proceeds onto other - DaemonSet pods, thus ensuring that at least 70% of original - number of DaemonSet pods are available at all times during - the update.' + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -13343,14 +12820,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for component - Docker images. If specified then the given value must end with a - slash character (`/`) and all images will be pulled from this registry. - If not specified then the default registries will be used. A special - case value, UseDefault, is supported to explicitly specify the default - registries will be used. \n Image format: `/:` - \n This option allows configuring the `` portion of the - above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -13359,24 +12836,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity characteristics - for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with the @@ -13386,30 +12862,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13422,30 +12894,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13467,60 +12935,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity requirements - specified by this field are not met at scheduling time, - the pod will NOT be scheduled onto the node. There is no - fallback to another affinity rules with this setting. This - may cause networking disruption or even catastrophic failure! - PreferredDuringSchedulingIgnoredDuringExecution should be - used for affinity unless there is a specific well understood - reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution is - set by default for AKS nodes, to avoid scheduling Typhas - on virtual-nodes. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13533,30 +12994,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13575,9 +13032,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. If used - in conjunction with the deprecated ComponentResources or TyphaAffinity, - then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's metadata @@ -13586,30 +13043,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to the - object's annotations provided the key does not already exist - in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values that - may match replicaset and service selectors. Each of these - key/value pairs are added to the object's labels provided - the key does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of seconds - for which a newly created Deployment pod should be ready - without any of its container crashing, for it to be considered - available. If specified, this overrides any minReadySeconds - value that may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -13619,45 +13075,43 @@ spec: pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present only - if DeploymentStrategyType = RollingUpdate. to be. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be scheduled above the desired number of pods. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). This can not be 0 if - MaxUnavailable is 0. Absolute number is calculated - from percentage by rounding up. Defaults to 25%. - Example: when this is set to 30%, the new ReplicaSet - can be scaled up immediately when the rolling update - starts, such that the total number of old and new - pods do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be scaled - up further, ensuring that total number of pods running - at any time during the update is at most 130% of - desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that can - be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of desired - pods (ex: 10%). Absolute number is calculated from - percentage by rounding down. This can not be 0 if - MaxSurge is 0. Defaults to 25%. Example: when this - is set to 30%, the old ReplicaSet can be scaled - down to 70% of desired pods immediately when the - rolling update starts. Once new pods are ready, - old ReplicaSet can be scaled down further, followed - by scaling up the new ReplicaSet, ensuring that - the total number of pods available at all times - during the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -13666,67 +13120,57 @@ spec: will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes object's - metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added - to the object's annotations provided the key does - not already exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. - Each of these key/value pairs are added to the object's - labels provided the key does not already exist in - the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity scheduling - rules for the typha pods. If specified, this overrides - any affinity that may be set on the typha Deployment. - If omitted, the typha Deployment will use its default - value for affinity. If used in conjunction with - the deprecated TyphaAffinity, then this value takes - precedence. WARNING: Please note that this field - will override the default calico-typha Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the - most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null preferred - scheduling term matches no objects (i.e. - is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -13736,9 +13180,8 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13747,27 +13190,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13780,9 +13213,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13791,27 +13223,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13834,31 +13256,28 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector - term matches no objects. The requirements - of them are ANDed. The TopologySelectorTerm - type implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13867,27 +13286,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13900,9 +13309,8 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains - values, a key, and an operator + description: |- + A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -13911,27 +13319,17 @@ spec: to. type: string operator: - description: Represents a - key's relationship to a - set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string - values. If the operator - is In or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the values - array must be empty. If - the operator is Gt or Lt, - the values array must have - a single element, which - will be interpreted as an - integer. This array is replaced - during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -13954,21 +13352,16 @@ spec: zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - affinity expressions specified by this field, - but it may choose a node that violates one - or more of the expressions. The node that - is most preferred is the one with the greatest - sum of weights, i.e. for each node that - meets all of the scheduling requirements - (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum - by iterating through the elements of this - field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest - sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -13990,10 +13383,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14002,24 +13393,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14032,30 +13414,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14063,10 +13435,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14075,24 +13445,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14105,51 +13466,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14159,28 +13505,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the affinity requirements specified - by this field cease to be met at some point - during pod execution (e.g. due to a pod - label update), the system may or may not - try to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -14191,11 +13531,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -14203,23 +13541,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -14231,39 +13562,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -14271,23 +13592,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -14299,41 +13613,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14346,21 +13648,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to - schedule pods to nodes that satisfy the - anti-affinity expressions specified by this - field, but it may choose a node that violates - one or more of the expressions. The node - that is most preferred is the one with the - greatest sum of weights, i.e. for each node - that meets all of the scheduling requirements - (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute - a sum by iterating through the elements - of this field and adding "weight" to the - sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added @@ -14382,10 +13679,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14394,24 +13689,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14424,30 +13710,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -14455,10 +13731,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -14467,24 +13741,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -14497,51 +13762,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -14551,28 +13801,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met at scheduling - time, the pod will not be scheduled onto - the node. If the anti-affinity requirements - specified by this field cease to be met - at some point during pod execution (e.g. - due to a pod label update), the system may - or may not try to eventually evict the pod - from its node. When there are multiple elements, - the lists of nodes corresponding to each - podAffinityTerm are intersected, i.e. all - terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this pod - should be co-located (affinity) or not - co-located (anti-affinity) with, where - co-located is defined as running on a - node whose value of the label with key - matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set @@ -14583,11 +13827,9 @@ spec: a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -14595,23 +13837,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -14623,39 +13858,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over the - set of namespaces that the term applies - to. The term is applied to the union - of the namespaces selected by this - field and the ones listed in the namespaces - field. null selector and null or empty - namespaces list means "this pod's - namespace". An empty selector ({}) - matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector that - contains values, a key, and - an operator that relates the - key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -14663,23 +13888,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to - a set of values. Valid operators - are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an - array of string values. - If the operator is In or - NotIn, the values array - must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be - empty. This array is replaced - during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -14691,41 +13909,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map - of {key,value} pairs. A single - {key,value} in the matchLabels - map is equivalent to an element - of matchExpressions, whose key - field is "key", the operator is - "In", and the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a - static list of namespace names that - the term applies to. The term is applied - to the union of the namespaces listed - in this field and the ones selected - by namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where - co-located is defined as running on - a node whose value of the label with - key topologyKey matches that of any - node on which any of the selected - pods is running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -14734,49 +13940,43 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha Deployment - will use its default values for its containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. Supported - values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment container's - resources. If omitted, the typha Deployment - will use its default value for this container's - resources. If used in conjunction with the - deprecated ComponentResources, then this value - takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -14793,9 +13993,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -14804,13 +14004,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -14818,50 +14016,43 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha init - containers. If specified, this overrides the specified - typha Deployment init containers. If omitted, the - typha Deployment will use its default values for - its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by name. - Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, this - overrides the named typha Deployment init - container's resources. If omitted, the typha - Deployment will use its default value for - this init container's resources. If used in - conjunction with the deprecated ComponentResources, - then this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names of - resources, defined in spec.resourceClaims, - that are used by this container. \n This - is an alpha field and requires enabling - the DynamicResourceAllocation feature - gate. \n This field is immutable. It can - only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -14878,9 +14069,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -14889,13 +14080,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -14905,97 +14094,81 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha pod''s - scheduling constraints. If specified, each of the - key/value pairs are added to the calico-typha Deployment - nodeSelector provided the key does not already exist - in the object''s nodeSelector. If omitted, the calico-typha - Deployment will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the pod - needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). If this - value is nil, the default grace period will be used - instead. The grace period is the duration in seconds - after the processes running in the pod are sent - a termination signal and the time when the processes - are forcibly halted with a kill signal. Set this - value longer than the expected cleanup time for - your process. Defaults to 30 seconds. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s tolerations. - If specified, this overrides any tolerations that - may be set on the typha Deployment. If omitted, - the typha Deployment will use its default value - for tolerations. WARNING: Please note that this - field will override the default calico-typha Deployment - tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect - to match. Empty means match all taint effects. - When specified, allowed values are NoSchedule, - PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. - If the key is empty, operator must be Exists; - this combination means to match all values - and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and - Equal. Defaults to Equal. Exists is equivalent - to wildcard for value, so that a pod can tolerate - all taints of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the - period of time the toleration (which must - be of effect NoExecute, otherwise this field - is ignored) tolerates the taint. By default, - it is not set, which means tolerate the taint - forever (do not evict). Zero and negative - values will be treated as 0 (evict immediately) - by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the - value should be empty, otherwise just a regular - string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes how - a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way which - abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find matching - pods. Pods that match this label selector - are counted to determine the number of pods + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. properties: matchExpressions: @@ -15003,30 +14176,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -15038,158 +14206,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of pod - label keys to select the pods over which spreading - will be calculated. The keys are used to lookup - values from the incoming pod labels, those - key-value labels are ANDed with labelSelector - to select the group of existing pods over - which spreading will be calculated for the - incoming pod. The same key is forbidden to - exist in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the incoming - pod labels will be ignored. A null or empty - list means only match against labelSelector. - \n This is a beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree to - which pods may be unevenly distributed. When - `whenUnsatisfiable=DoNotSchedule`, it is the - maximum permitted difference between the number - of matching pods in the target topology and - the global minimum. The global minimum is - the minimum number of matching pods in an - eligible domain or zero if the number of eligible - domains is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to 1, - and pods with the same labelSelector spread - as 2/2/1: In this case, the global minimum - is 1. | zone1 | zone2 | zone3 | | P P | P - P | P | - if MaxSkew is 1, incoming pod - can only be scheduled to zone3 to become 2/2/2; - scheduling it onto zone1(zone2) would make - the ActualSkew(3-1) on zone1(zone2) violate - MaxSkew(1). - if MaxSkew is 2, incoming pod - can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies - that satisfy it. It''s a required field. Default - value is 1 and 0 is not allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, and - then the calculation of Skew is performed. - And when the number of eligible domains with - matching topology keys equals or greater than - minDomains, this value has no effect on scheduling. - As a result, when the number of eligible domains - is less than minDomains, scheduler won't schedule - more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if - MinDomains is equal to 1. Valid values are - integers greater than 0. When value is not - nil, WhenUnsatisfiable must be DoNotSchedule. - \n For example, in a 3-zone cluster, MaxSkew - is set to 2, MinDomains is set to 5 and pods - with the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P P | - \ P P | The number of domains is less than - 5(MinDomains), so \"global minimum\" is treated - as 0. In this situation, new pod with the - same labelSelector cannot be scheduled, because - computed skew will be 3(3 - 0) if new Pod - is scheduled to any of the three zones, it - will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread - feature gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how - we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included in - the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the - calculations. \n If this value is nil, the - behavior is equivalent to the Honor policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how - we will treat node taints when calculating - pod topology spread skew. Options are: - Honor: - nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, - are included. - Ignore: node taints are ignored. - All nodes are included. \n If this value is - nil, the behavior is equivalent to the Ignore - policy. This is a beta-level feature default - enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered to - be in the same topology. We consider each - as a "bucket", and try to put - balanced number of pods into each bucket. - We define a domain as a particular instance - of a topology. Also, we define an eligible - domain as a domain whose nodes meet the requirements - of nodeAffinityPolicy and nodeTaintsPolicy. - e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, - if TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. It's - a required field. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how - to deal with a pod if it doesn''t satisfy - the spread constraint. - DoNotSchedule (default) - tells the scheduler not to schedule it. - - ScheduleAnyway tells the scheduler to schedule - the pod in any location, but giving higher - precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" - for an incoming pod if and only if every possible - node assignment for that pod would violate - "MaxSkew" on some topology. For example, in - a 3-zone cluster, MaxSkew is set to 1, and - pods with the same labelSelector spread as - 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, - incoming pod can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). In other - words, the cluster can still be imbalanced, - but scheduler won''t make it *more* imbalanced. - It''s a required field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -15207,8 +14341,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico or - TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -15217,15 +14352,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under [plugins] - [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -15248,18 +14387,19 @@ spec: installation. properties: calicoVersion: - description: CalicoVersion shows the current running version of calico. - CalicoVersion along with Variant is needed to know the exact version - deployed. + description: |- + CalicoVersion shows the current running version of calico. + CalicoVersion along with Variant is needed to know the exact + version deployed. type: string computed: description: Computed is the final installation including overlaid resources. properties: calicoKubeControllersDeployment: - description: CalicoKubeControllersDeployment configures the calico-kube-controllers - Deployment. If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoKubeControllersDeployment configures the calico-kube-controllers Deployment. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -15268,19 +14408,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15288,13 +14427,11 @@ spec: Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -15304,26 +14441,25 @@ spec: Deployment pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -15331,43 +14467,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-kube-controllers - pods. If specified, this overrides any affinity - that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-kube-controllers pods. + If specified, this overrides any affinity that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for affinity. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -15379,11 +14503,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15391,30 +14513,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15428,11 +14537,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15440,30 +14547,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15486,36 +14580,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15523,30 +14611,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15560,11 +14635,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -15572,30 +14645,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -15618,22 +14678,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -15656,12 +14710,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15670,27 +14721,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15703,33 +14742,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15737,12 +14763,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -15751,27 +14774,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15784,55 +14795,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -15842,30 +14834,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -15878,10 +14862,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15890,24 +14872,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15920,30 +14893,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -15951,10 +14914,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -15963,24 +14924,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -15993,44 +14945,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -16043,22 +14980,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -16081,12 +15012,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16095,27 +15023,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16128,33 +15044,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16162,12 +15065,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -16176,27 +15076,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16209,55 +15097,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -16267,30 +15136,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -16303,10 +15164,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16315,24 +15174,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16345,30 +15195,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -16376,10 +15216,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -16388,24 +15226,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -16418,44 +15247,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -16464,54 +15278,45 @@ spec: type: object type: object containers: - description: Containers is a list of calico-kube-controllers - containers. If specified, this overrides the - specified calico-kube-controllers Deployment - containers. If omitted, the calico-kube-controllers - Deployment will use its default values for its - containers. + description: |- + Containers is a list of calico-kube-controllers containers. + If specified, this overrides the specified calico-kube-controllers Deployment containers. + If omitted, the calico-kube-controllers Deployment will use its default values for its containers. items: description: CalicoKubeControllersDeploymentContainer is a calico-kube-controllers Deployment container. properties: name: - description: 'Name is an enum which identifies - the calico-kube-controllers Deployment - container by name. Supported values are: - calico-kube-controllers' + description: |- + Name is an enum which identifies the calico-kube-controllers Deployment container by name. + Supported values are: calico-kube-controllers, es-calico-kube-controllers enum: - calico-kube-controllers + - es-calico-kube-controllers type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-kube-controllers - Deployment container's resources. If omitted, - the calico-kube-controllers Deployment - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-kube-controllers Deployment container's resources. + If omitted, the calico-kube-controllers Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -16527,9 +15332,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -16538,14 +15343,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -16555,76 +15357,56 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-kube-controllers - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-kube-controllers Deployment nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If used in conjunction - with ControlPlaneNodeSelector, that nodeSelector - is set on the calico-kube-controllers Deployment - and each of this field''s key/value pairs are - added to the calico-kube-controllers Deployment - nodeSelector provided the key does not already - exist in the object''s nodeSelector. If omitted, - the calico-kube-controllers Deployment will - use its default value for nodeSelector. WARNING: - Please note that this field will modify the - default calico-kube-controllers Deployment nodeSelector.' + description: |- + NodeSelector is the calico-kube-controllers pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If used in conjunction with ControlPlaneNodeSelector, that nodeSelector is set on the calico-kube-controllers Deployment + and each of this field's key/value pairs are added to the calico-kube-controllers Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-kube-controllers Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-kube-controllers Deployment nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-kube-controllers - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-kube-controllers - Deployment. If omitted, the calico-kube-controllers - Deployment will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-kube-controllers Deployment - tolerations.' + description: |- + Tolerations is the calico-kube-controllers pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-kube-controllers Deployment. + If omitted, the calico-kube-controllers Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-kube-controllers Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -16644,39 +15426,39 @@ spec: - Disabled type: string containerIPForwarding: - description: 'ContainerIPForwarding configures whether ip - forwarding will be enabled for containers in the CNI configuration. - Default: Disabled' + description: |- + ContainerIPForwarding configures whether ip forwarding will be enabled for containers in the CNI configuration. + Default: Disabled enum: - Enabled - Disabled type: string hostPorts: - description: 'HostPorts configures whether or not Calico will - support Kubernetes HostPorts. Valid only when using the - Calico CNI plugin. Default: Enabled' + description: |- + HostPorts configures whether or not Calico will support Kubernetes HostPorts. Valid only when using the Calico CNI plugin. + Default: Enabled enum: - Enabled - Disabled type: string ipPools: - description: IPPools contains a list of IP pools to create - if none exist. At most one IP pool of each address family - may be specified. If omitted, a single pool will be configured - if needed. + description: |- + IPPools contains a list of IP pools to create if none exist. At most one IP pool of each + address family may be specified. If omitted, a single pool will be configured if needed. items: properties: allowedUses: - description: AllowedUse controls what the IP pool will - be used for. If not specified or empty, defaults - to ["Tunnel", "Workload"] for back-compatibility + description: |- + AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to + ["Tunnel", "Workload"] for back-compatibility items: type: string type: array blockSize: - description: 'BlockSize specifies the CIDR prefex length - to use when allocating per-node IP blocks from the - main IP pool CIDR. Default: 26 (IPv4), 122 (IPv6)' + description: |- + BlockSize specifies the CIDR prefex length to use when allocating per-node IP blocks from + the main IP pool CIDR. + Default: 26 (IPv4), 122 (IPv6) format: int32 type: integer cidr: @@ -16685,14 +15467,15 @@ spec: type: string disableBGPExport: default: false - description: 'DisableBGPExport specifies whether routes - from this IP pool''s CIDR are exported over BGP. Default: - false' + description: |- + DisableBGPExport specifies whether routes from this IP pool's CIDR are exported over BGP. + Default: false type: boolean encapsulation: - description: 'Encapsulation specifies the encapsulation - type that will be used with the IP Pool. Default: - IPIP' + description: |- + Encapsulation specifies the encapsulation type that will be used with + the IP Pool. + Default: IPIP enum: - IPIPCrossSubnet - IPIP @@ -16705,15 +15488,17 @@ spec: this will be generated. type: string natOutgoing: - description: 'NATOutgoing specifies if NAT will be enabled - or disabled for outgoing traffic. Default: Enabled' + description: |- + NATOutgoing specifies if NAT will be enabled or disabled for outgoing traffic. + Default: Enabled enum: - Enabled - Disabled type: string nodeSelector: - description: 'NodeSelector specifies the node selector - that will be set for the IP Pool. Default: ''all()''' + description: |- + NodeSelector specifies the node selector that will be set for the IP Pool. + Default: 'all()' type: string required: - cidr @@ -16721,61 +15506,63 @@ spec: maxItems: 25 type: array linuxDataplane: - description: 'LinuxDataplane is used to select the dataplane - used for Linux nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, iptables mode is - used. Default: Iptables' + description: |- + LinuxDataplane is used to select the dataplane used for Linux nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, iptables mode is used. + Default: Iptables enum: - Iptables - BPF - VPP + - Nftables type: string linuxPolicySetupTimeoutSeconds: - description: "LinuxPolicySetupTimeoutSeconds delays new pods - from running containers until their policy has been programmed - in the dataplane. The specified delay defines the maximum - amount of time that the Calico CNI plugin will wait for - policy to be programmed. \n Only applies to pods created - on Linux nodes. \n * A value of 0 disables pod startup delays. - \n Default: 0" + description: |- + LinuxPolicySetupTimeoutSeconds delays new pods from running containers + until their policy has been programmed in the dataplane. + The specified delay defines the maximum amount of time + that the Calico CNI plugin will wait for policy to be programmed. + Only applies to pods created on Linux nodes. + * A value of 0 disables pod startup delays. + Default: 0 format: int32 type: integer mtu: - description: MTU specifies the maximum transmission unit to - use on the pod network. If not specified, Calico will perform - MTU auto-detection based on the cluster network. + description: |- + MTU specifies the maximum transmission unit to use on the pod network. + If not specified, Calico will perform MTU auto-detection based on the cluster network. format: int32 type: integer multiInterfaceMode: - description: 'MultiInterfaceMode configures what will configure - multiple interface per pod. Only valid for Calico Enterprise - installations using the Calico CNI plugin. Default: None' + description: |- + MultiInterfaceMode configures what will configure multiple interface per pod. Only valid for Calico Enterprise installations + using the Calico CNI plugin. + Default: None enum: - None - Multus type: string nodeAddressAutodetectionV4: - description: NodeAddressAutodetectionV4 specifies an approach - to automatically detect node IPv4 addresses. If not specified, - will use default auto-detection settings to acquire an IPv4 - address for each node. + description: |- + NodeAddressAutodetectionV4 specifies an approach to automatically detect node IPv4 addresses. If not specified, + will use default auto-detection settings to acquire an IPv4 address for each node. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -16789,30 +15576,31 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object nodeAddressAutodetectionV6: - description: NodeAddressAutodetectionV6 specifies an approach - to automatically detect node IPv6 addresses. If not specified, + description: |- + NodeAddressAutodetectionV6 specifies an approach to automatically detect node IPv6 addresses. If not specified, IPv6 addresses will not be auto-detected. properties: canReach: - description: CanReach enables IP auto-detection based - on which source address on the node is used to reach - the specified IP or domain. + description: |- + CanReach enables IP auto-detection based on which source address on the node is used to reach the + specified IP or domain. type: string cidrs: - description: CIDRS enables IP auto-detection based on - which addresses on the nodes are within one of the provided - CIDRs. + description: |- + CIDRS enables IP auto-detection based on which addresses on the nodes are within + one of the provided CIDRs. items: type: string type: array firstFound: - description: FirstFound uses default interface matching - parameters to select an interface, performing best-effort + description: |- + FirstFound uses default interface matching parameters to select an interface, performing best-effort filtering based on well-known interface names. type: boolean interface: @@ -16826,8 +15614,9 @@ spec: - NodeInternalIP type: string skipInterface: - description: SkipInterface enables IP auto-detection based - on interfaces that do not match the given regex. + description: |- + SkipInterface enables IP auto-detection based on interfaces that do not match + the given regex. type: string type: object sysctl: @@ -16849,21 +15638,20 @@ spec: type: object type: array windowsDataplane: - description: 'WindowsDataplane is used to select the dataplane - used for Windows nodes. In particular, it causes the operator - to add required mounts and environment variables for the - particular dataplane. If not specified, it is disabled and - the operator will not render the Calico Windows nodes daemonset. - Default: Disabled' + description: |- + WindowsDataplane is used to select the dataplane used for Windows nodes. In particular, it + causes the operator to add required mounts and environment variables for the particular dataplane. + If not specified, it is disabled and the operator will not render the Calico Windows nodes daemonset. + Default: Disabled enum: - HNS - Disabled type: string type: object calicoNodeDaemonSet: - description: CalicoNodeDaemonSet configures the calico-node DaemonSet. - If used in conjunction with the deprecated ComponentResources, - then these overrides take precedence. + description: |- + CalicoNodeDaemonSet configures the calico-node DaemonSet. If used in + conjunction with the deprecated ComponentResources, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -16872,19 +15660,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -16892,13 +15679,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet will - use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -16908,68 +15693,56 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the calico-node DaemonSet's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node pods. If - specified, this overrides any affinity that - may be set on the calico-node DaemonSet. If - omitted, the calico-node DaemonSet will use - its default value for affinity. WARNING: Please - note that this field will override the default - calico-node DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node pods. + If specified, this overrides any affinity that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -16981,11 +15754,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -16993,30 +15764,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17030,11 +15788,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17042,30 +15798,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17088,36 +15831,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17125,30 +15862,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17162,11 +15886,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -17174,30 +15896,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -17220,22 +15929,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17258,12 +15961,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17272,27 +15972,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17305,33 +15993,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17339,12 +16014,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17353,27 +16025,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17386,55 +16046,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -17444,30 +16085,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -17480,10 +16113,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17492,24 +16123,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17522,30 +16144,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17553,10 +16165,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17565,24 +16175,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17595,44 +16196,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -17645,22 +16231,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -17683,12 +16263,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17697,27 +16274,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17730,33 +16295,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17764,12 +16316,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -17778,27 +16327,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17811,55 +16348,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -17869,30 +16387,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -17905,10 +16415,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17917,24 +16425,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -17947,30 +16446,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -17978,10 +16467,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -17990,24 +16477,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18020,44 +16498,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -18066,52 +16529,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node - containers. If specified, this overrides the - specified calico-node DaemonSet containers. - If omitted, the calico-node DaemonSet will use - its default values for its containers. + description: |- + Containers is a list of calico-node containers. + If specified, this overrides the specified calico-node DaemonSet containers. + If omitted, the calico-node DaemonSet will use its default values for its containers. items: description: CalicoNodeDaemonSetContainer is a calico-node DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet container by - name. Supported values are: calico-node' + description: |- + Name is an enum which identifies the calico-node DaemonSet container by name. + Supported values are: calico-node enum: - calico-node type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - container's resources. If omitted, the - calico-node DaemonSet will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18127,9 +16582,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18138,14 +16593,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18153,21 +16605,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node - init containers. If specified, this overrides - the specified calico-node DaemonSet init containers. - If omitted, the calico-node DaemonSet will use - its default values for its init containers. + description: |- + InitContainers is a list of calico-node init containers. + If specified, this overrides the specified calico-node DaemonSet init containers. + If omitted, the calico-node DaemonSet will use its default values for its init containers. items: description: CalicoNodeDaemonSetInitContainer is a calico-node DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node DaemonSet init container - by name. Supported values are: install-cni, - hostpath-init, flexvol-driver, mount-bpffs, - node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node DaemonSet init container by name. + Supported values are: install-cni, hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -18177,35 +16626,28 @@ spec: - calico-node-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node DaemonSet - init container's resources. If omitted, - the calico-node DaemonSet will use its - default value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node DaemonSet init container's resources. + If omitted, the calico-node DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -18221,9 +16663,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -18232,14 +16674,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -18249,68 +16688,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node DaemonSet - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the calico-node - DaemonSet. If omitted, the calico-node DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node DaemonSet tolerations.' + description: |- + Tolerations is the calico-node pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node DaemonSet. + If omitted, the calico-node DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -18329,19 +16753,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -18349,13 +16772,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -18365,26 +16786,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -18392,42 +16812,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-node-windows - pods. If specified, this overrides any affinity - that may be set on the calico-node-windows DaemonSet. - If omitted, the calico-node-windows DaemonSet - will use its default value for affinity. WARNING: - Please note that this field will override the - default calico-node-windows DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-node-windows pods. + If specified, this overrides any affinity that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -18439,11 +16848,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -18451,30 +16858,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18488,11 +16882,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -18500,30 +16892,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18546,36 +16925,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -18583,30 +16956,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18620,11 +16980,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -18632,30 +16990,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -18678,22 +17023,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -18716,12 +17055,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -18730,27 +17066,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18763,33 +17087,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -18797,12 +17108,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -18811,27 +17119,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18844,55 +17140,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -18902,30 +17179,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -18938,10 +17207,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -18950,24 +17217,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -18980,30 +17238,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19011,10 +17259,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19023,24 +17269,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19053,44 +17290,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -19103,22 +17325,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -19141,12 +17357,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -19155,27 +17368,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19188,33 +17389,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19222,12 +17410,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -19236,27 +17421,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19269,55 +17442,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -19327,30 +17481,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -19363,10 +17509,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19375,24 +17519,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19405,30 +17540,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -19436,10 +17561,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -19448,24 +17571,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -19478,44 +17592,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -19524,52 +17623,44 @@ spec: type: object type: object containers: - description: Containers is a list of calico-node-windows - containers. If specified, this overrides the - specified calico-node-windows DaemonSet containers. - If omitted, the calico-node-windows DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-node-windows containers. + If specified, this overrides the specified calico-node-windows DaemonSet containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its containers. items: description: CalicoNodeWindowsDaemonSetContainer is a calico-node-windows DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet container - by name. Supported values are: calico-node-windows' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet container by name. + Supported values are: calico-node-windows enum: - calico-node-windows type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet container's resources. If omitted, - the calico-node-windows DaemonSet will - use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -19585,9 +17676,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -19596,14 +17687,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -19611,23 +17699,18 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of calico-node-windows - init containers. If specified, this overrides - the specified calico-node-windows DaemonSet - init containers. If omitted, the calico-node-windows - DaemonSet will use its default values for its - init containers. + description: |- + InitContainers is a list of calico-node-windows init containers. + If specified, this overrides the specified calico-node-windows DaemonSet init containers. + If omitted, the calico-node-windows DaemonSet will use its default values for its init containers. items: description: CalicoNodeWindowsDaemonSetInitContainer is a calico-node-windows DaemonSet init container. properties: name: - description: 'Name is an enum which identifies - the calico-node-windows DaemonSet init - container by name. Supported values are: - install-cni;hostpath-init, flexvol-driver, - mount-bpffs, node-certs-key-cert-provisioner, - calico-node-windows-prometheus-server-tls-key-cert-provisioner' + description: |- + Name is an enum which identifies the calico-node-windows DaemonSet init container by name. + Supported values are: install-cni;hostpath-init, flexvol-driver, mount-bpffs, node-certs-key-cert-provisioner, calico-node-windows-prometheus-server-tls-key-cert-provisioner enum: - install-cni - hostpath-init @@ -19637,35 +17720,28 @@ spec: - calico-node-windows-prometheus-server-tls-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-node-windows - DaemonSet init container's resources. - If omitted, the calico-node-windows DaemonSet - will use its default value for this container's - resources. If used in conjunction with - the deprecated ComponentResources, then - this value takes precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-node-windows DaemonSet init container's resources. + If omitted, the calico-node-windows DaemonSet will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -19681,9 +17757,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -19692,14 +17768,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -19709,68 +17782,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-node-windows - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-node-windows DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-node-windows - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-node-windows DaemonSet nodeSelector.' + description: |- + NodeSelector is the calico-node-windows pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-node-windows DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-node-windows DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-node-windows DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-node-windows - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-node-windows - DaemonSet. If omitted, the calico-node-windows - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-node-windows DaemonSet tolerations.' + description: |- + Tolerations is the calico-node-windows pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-node-windows DaemonSet. + If omitted, the calico-node-windows DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-node-windows DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -19779,9 +17837,9 @@ spec: type: object type: object calicoWindowsUpgradeDaemonSet: - description: Deprecated. The CalicoWindowsUpgradeDaemonSet is - deprecated and will be removed from the API in the future. CalicoWindowsUpgradeDaemonSet - configures the calico-windows-upgrade DaemonSet. + description: |- + Deprecated. The CalicoWindowsUpgradeDaemonSet is deprecated and will be removed from the API in the future. + CalicoWindowsUpgradeDaemonSet configures the calico-windows-upgrade DaemonSet. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -19790,19 +17848,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -19810,13 +17867,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -19826,26 +17881,25 @@ spec: DaemonSet pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -19853,43 +17907,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the calico-windows-upgrade - pods. If specified, this overrides any affinity - that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for affinity. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the calico-windows-upgrade pods. + If specified, this overrides any affinity that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -19901,11 +17943,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -19913,30 +17953,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -19950,11 +17977,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -19962,30 +17987,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -20008,36 +18020,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -20045,30 +18051,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -20082,11 +18075,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -20094,30 +18085,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -20140,22 +18118,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -20178,12 +18150,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -20192,27 +18161,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20225,33 +18182,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -20259,12 +18203,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -20273,27 +18214,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20306,55 +18235,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -20364,30 +18274,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -20400,10 +18302,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -20412,24 +18312,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20442,30 +18333,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -20473,10 +18354,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -20485,24 +18364,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20515,44 +18385,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -20565,22 +18420,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -20603,12 +18452,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -20617,27 +18463,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20650,33 +18484,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -20684,12 +18505,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -20698,27 +18516,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20731,55 +18537,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -20789,30 +18576,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -20825,10 +18604,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -20837,24 +18614,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20867,30 +18635,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -20898,10 +18656,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -20910,24 +18666,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -20940,44 +18687,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -20986,11 +18718,10 @@ spec: type: object type: object containers: - description: Containers is a list of calico-windows-upgrade - containers. If specified, this overrides the - specified calico-windows-upgrade DaemonSet containers. - If omitted, the calico-windows-upgrade DaemonSet - will use its default values for its containers. + description: |- + Containers is a list of calico-windows-upgrade containers. + If specified, this overrides the specified calico-windows-upgrade DaemonSet containers. + If omitted, the calico-windows-upgrade DaemonSet will use its default values for its containers. items: description: CalicoWindowsUpgradeDaemonSetContainer is a calico-windows-upgrade DaemonSet container. @@ -21003,33 +18734,27 @@ spec: - calico-windows-upgrade type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named calico-windows-upgrade - DaemonSet container's resources. If omitted, - the calico-windows-upgrade DaemonSet will - use its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named calico-windows-upgrade DaemonSet container's resources. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -21045,9 +18770,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -21056,14 +18781,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -21073,70 +18795,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-windows-upgrade - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-windows-upgrade DaemonSet nodeSelector - provided the key does not already exist in the - object''s nodeSelector. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-windows-upgrade DaemonSet - nodeSelector.' + description: |- + NodeSelector is the calico-windows-upgrade pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-windows-upgrade DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-windows-upgrade DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the calico-windows-upgrade - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the calico-windows-upgrade - DaemonSet. If omitted, the calico-windows-upgrade - DaemonSet will use its default value for tolerations. - WARNING: Please note that this field will override - the default calico-windows-upgrade DaemonSet - tolerations.' + description: |- + Tolerations is the calico-windows-upgrade pod's tolerations. + If specified, this overrides any tolerations that may be set on the calico-windows-upgrade DaemonSet. + If omitted, the calico-windows-upgrade DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-windows-upgrade DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -21145,10 +18850,9 @@ spec: type: object type: object certificateManagement: - description: CertificateManagement configures pods to submit a - CertificateSigningRequest to the certificates.k8s.io/v1beta1 - API in order to obtain TLS certificates. This feature requires - that you bring your own CSR signing and approval process, otherwise + description: |- + CertificateManagement configures pods to submit a CertificateSigningRequest to the certificates.k8s.io/v1beta1 API in order + to obtain TLS certificates. This feature requires that you bring your own CSR signing and approval process, otherwise pods will be stuck during initialization. properties: caCert: @@ -21157,9 +18861,9 @@ spec: format: byte type: string keyAlgorithm: - description: 'Specify the algorithm used by pods to generate - a key pair that is associated with the X.509 certificate - request. Default: RSAWithSize2048' + description: |- + Specify the algorithm used by pods to generate a key pair that is associated with the X.509 certificate request. + Default: RSAWithSize2048 enum: - "" - RSAWithSize2048 @@ -21170,8 +18874,9 @@ spec: - ECDSAWithCurve521 type: string signatureAlgorithm: - description: 'Specify the algorithm used for the signature - of the X.509 certificate request. Default: SHA256WithRSA' + description: |- + Specify the algorithm used for the signature of the X.509 certificate request. + Default: SHA256WithRSA enum: - "" - SHA256WithRSA @@ -21182,10 +18887,10 @@ spec: - ECDSAWithSHA512 type: string signerName: - description: 'When a CSR is issued to the certificates.k8s.io - API, the signerName is added to the request in order to - accommodate for clusters with multiple signers. Must be - formatted as: `/`.' + description: |- + When a CSR is issued to the certificates.k8s.io API, the signerName is added to the request in order to accommodate for clusters + with multiple signers. + Must be formatted as: `/`. type: string required: - caCert @@ -21195,21 +18900,21 @@ spec: description: CNI specifies the CNI that will be used by this installation. properties: ipam: - description: IPAM specifies the pod IP address management - that will be used in the Calico or Calico Enterprise installation. + description: |- + IPAM specifies the pod IP address management that will be used in the Calico or + Calico Enterprise installation. properties: type: - description: "Specifies the IPAM plugin that will be used - in the Calico or Calico Enterprise installation. * For - CNI Plugin Calico, this field defaults to Calico. * - For CNI Plugin GKE, this field defaults to HostLocal. + description: |- + Specifies the IPAM plugin that will be used in the Calico or Calico Enterprise installation. + * For CNI Plugin Calico, this field defaults to Calico. + * For CNI Plugin GKE, this field defaults to HostLocal. * For CNI Plugin AzureVNET, this field defaults to AzureVNET. * For CNI Plugin AmazonVPC, this field defaults to AmazonVPC. - \n The IPAM plugin is installed and configured only - if the CNI plugin is set to Calico, for all other values - of the CNI plugin the plugin binaries and CNI config - is a dependency that is expected to be installed separately. - \n Default: Calico" + The IPAM plugin is installed and configured only if the CNI plugin is set to Calico, + for all other values of the CNI plugin the plugin binaries and CNI config is a dependency + that is expected to be installed separately. + Default: Calico enum: - Calico - HostLocal @@ -21220,18 +18925,17 @@ spec: - type type: object type: - description: "Specifies the CNI plugin that will be used in - the Calico or Calico Enterprise installation. * For KubernetesProvider - GKE, this field defaults to GKE. * For KubernetesProvider - AKS, this field defaults to AzureVNET. * For KubernetesProvider - EKS, this field defaults to AmazonVPC. * If aws-node daemonset - exists in kube-system when the Installation resource is - created, this field defaults to AmazonVPC. * For all other - cases this field defaults to Calico. \n For the value Calico, - the CNI plugin binaries and CNI config will be installed - as part of deployment, for all other values the CNI plugin - binaries and CNI config is a dependency that is expected - to be installed separately. \n Default: Calico" + description: |- + Specifies the CNI plugin that will be used in the Calico or Calico Enterprise installation. + * For KubernetesProvider GKE, this field defaults to GKE. + * For KubernetesProvider AKS, this field defaults to AzureVNET. + * For KubernetesProvider EKS, this field defaults to AmazonVPC. + * If aws-node daemonset exists in kube-system when the Installation resource is created, this field defaults to AmazonVPC. + * For all other cases this field defaults to Calico. + For the value Calico, the CNI plugin binaries and CNI config will be installed as part of deployment, + for all other values the CNI plugin binaries and CNI config is a dependency that is expected + to be installed separately. + Default: Calico enum: - Calico - GKE @@ -21242,15 +18946,14 @@ spec: - type type: object componentResources: - description: Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, - and KubeControllersDeployment. ComponentResources can be used - to customize the resource requirements for each component. Node, - Typha, and KubeControllers are supported for installations. + description: |- + Deprecated. Please use CalicoNodeDaemonSet, TyphaDeployment, and KubeControllersDeployment. + ComponentResources can be used to customize the resource requirements for each component. + Node, Typha, and KubeControllers are supported for installations. items: - description: Deprecated. Please use component resource config - fields in Installation.Spec instead. The ComponentResource - struct associates a ResourceRequirements with a component - by name + description: |- + Deprecated. Please use component resource config fields in Installation.Spec instead. + The ComponentResource struct associates a ResourceRequirements with a component by name properties: componentName: description: ComponentName is an enum which identifies the @@ -21266,19 +18969,20 @@ spec: and memory. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. \n This field - is immutable. It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where - this field is used. It makes that resource available + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available inside a container. type: string required: @@ -21295,8 +18999,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -21305,11 +19010,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -21320,56 +19025,54 @@ spec: controlPlaneNodeSelector: additionalProperties: type: string - description: ControlPlaneNodeSelector is used to select control - plane nodes on which to run Calico components. This is globally - applied to all resources created by the operator excluding daemonsets. + description: |- + ControlPlaneNodeSelector is used to select control plane nodes on which to run Calico + components. This is globally applied to all resources created by the operator excluding daemonsets. type: object controlPlaneReplicas: - description: ControlPlaneReplicas defines how many replicas of - the control plane core components will be deployed. This field - applies to all control plane components that support High Availability. - Defaults to 2. + description: |- + ControlPlaneReplicas defines how many replicas of the control plane core components will be deployed. + This field applies to all control plane components that support High Availability. Defaults to 2. format: int32 type: integer controlPlaneTolerations: - description: ControlPlaneTolerations specify tolerations which - are then globally applied to all resources created by the operator. + description: |- + ControlPlaneTolerations specify tolerations which are then globally applied to all resources + created by the operator. items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -21384,19 +19087,18 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -21404,13 +19106,11 @@ spec: DaemonSet. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created DaemonSet pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created DaemonSet pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -21420,26 +19120,25 @@ spec: pod that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: @@ -21447,42 +19146,31 @@ spec: PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the csi-node-driver pods. - If specified, this overrides any affinity that - may be set on the csi-node-driver DaemonSet. - If omitted, the csi-node-driver DaemonSet will - use its default value for affinity. WARNING: - Please note that this field will override the - default csi-node-driver DaemonSet affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the csi-node-driver pods. + If specified, this overrides any affinity that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for affinity. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -21494,11 +19182,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -21506,30 +19192,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -21543,11 +19216,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -21555,30 +19226,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -21601,36 +19259,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -21638,30 +19290,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -21675,11 +19314,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -21687,30 +19324,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -21733,22 +19357,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -21771,12 +19389,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -21785,27 +19400,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -21818,33 +19421,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -21852,12 +19442,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -21866,27 +19453,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -21899,55 +19474,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -21957,30 +19513,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -21993,10 +19541,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -22005,24 +19551,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -22035,30 +19572,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -22066,10 +19593,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -22078,24 +19603,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -22108,44 +19624,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -22158,22 +19659,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -22196,12 +19691,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -22210,27 +19702,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -22243,33 +19723,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -22277,12 +19744,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -22291,27 +19755,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -22324,55 +19776,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -22382,30 +19815,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -22418,10 +19843,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -22430,24 +19853,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -22460,30 +19874,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -22491,10 +19895,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -22503,24 +19905,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -22533,44 +19926,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -22579,50 +19957,45 @@ spec: type: object type: object containers: - description: Containers is a list of csi-node-driver - containers. If specified, this overrides the - specified csi-node-driver DaemonSet containers. - If omitted, the csi-node-driver DaemonSet will - use its default values for its containers. + description: |- + Containers is a list of csi-node-driver containers. + If specified, this overrides the specified csi-node-driver DaemonSet containers. + If omitted, the csi-node-driver DaemonSet will use its default values for its containers. items: description: CSINodeDriverDaemonSetContainer is a csi-node-driver DaemonSet container. properties: name: - description: 'Name is an enum which identifies - the csi-node-driver DaemonSet container - by name. Supported values are: csi-node-driver' + description: |- + Name is an enum which identifies the csi-node-driver DaemonSet container by name. + Supported values are: calico-csi, csi-node-driver-registrar. enum: + - calico-csi + - csi-node-driver-registrar - csi-node-driver type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named csi-node-driver - DaemonSet container's resources. If omitted, - the csi-node-driver DaemonSet will use - its default value for this container's - resources. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named csi-node-driver DaemonSet container's resources. + If omitted, the csi-node-driver DaemonSet will use its default value for this container's resources. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -22638,9 +20011,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -22649,14 +20022,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -22666,68 +20036,53 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the csi-node-driver - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - csi-node-driver DaemonSet nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the csi-node-driver - DaemonSet will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default csi-node-driver DaemonSet nodeSelector.' + description: |- + NodeSelector is the csi-node-driver pod's scheduling constraints. + If specified, each of the key/value pairs are added to the csi-node-driver DaemonSet nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the csi-node-driver DaemonSet will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default csi-node-driver DaemonSet nodeSelector. type: object tolerations: - description: 'Tolerations is the csi-node-driver - pod''s tolerations. If specified, this overrides - any tolerations that may be set on the csi-node-driver - DaemonSet. If omitted, the csi-node-driver DaemonSet - will use its default value for tolerations. - WARNING: Please note that this field will override - the default csi-node-driver DaemonSet tolerations.' + description: |- + Tolerations is the csi-node-driver pod's tolerations. + If specified, this overrides any tolerations that may be set on the csi-node-driver DaemonSet. + If omitted, the csi-node-driver DaemonSet will use its default value for tolerations. + WARNING: Please note that this field will override the default csi-node-driver DaemonSet tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -22736,68 +20091,71 @@ spec: type: object type: object fipsMode: - description: 'FIPSMode uses images and features only that are - using FIPS 140-2 validated cryptographic modules and standards. - Default: Disabled' + description: |- + FIPSMode uses images and features only that are using FIPS 140-2 validated cryptographic modules and standards. + Default: Disabled enum: - Enabled - Disabled type: string flexVolumePath: - description: FlexVolumePath optionally specifies a custom path - for FlexVolume. If not specified, FlexVolume will be enabled - by default. If set to 'None', FlexVolume will be disabled. The - default is based on the kubernetesProvider. + description: |- + FlexVolumePath optionally specifies a custom path for FlexVolume. If not specified, FlexVolume will be + enabled by default. If set to 'None', FlexVolume will be disabled. The default is based on the + kubernetesProvider. type: string imagePath: - description: "ImagePath allows for the path part of an image to - be specified. If specified then the specified value will be - used as the image path for each image. If not specified or empty, - the default for each image will be used. A special case value, - UseDefault, is supported to explicitly specify the default image - path will be used for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePath allows for the path part of an image to be specified. If specified + then the specified value will be used as the image path for each image. If not specified + or empty, the default for each image will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image path will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePrefix: - description: "ImagePrefix allows for the prefix part of an image - to be specified. If specified then the given value will be used - as a prefix on each image. If not specified or empty, no prefix - will be used. A special case value, UseDefault, is supported - to explicitly specify the default image prefix will be used - for each image. \n Image format: `/:` - \n This option allows configuring the `` portion - of the above format." + description: |- + ImagePrefix allows for the prefix part of an image to be specified. If specified + then the given value will be used as a prefix on each image. If not specified + or empty, no prefix will be used. + A special case value, UseDefault, is supported to explicitly specify the default + image prefix will be used for each image. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string imagePullSecrets: - description: ImagePullSecrets is an array of references to container - registry pull secrets to use. These are applied to all images - to be pulled. + description: |- + ImagePullSecrets is an array of references to container registry pull secrets to use. These are + applied to all images to be pulled. items: - description: LocalObjectReference contains enough information - to let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic type: array kubeletVolumePluginPath: - description: 'KubeletVolumePluginPath optionally specifies enablement - of Calico CSI plugin. If not specified, CSI will be enabled - by default. If set to ''None'', CSI will be disabled. Default: - /var/lib/kubelet' + description: |- + KubeletVolumePluginPath optionally specifies enablement of Calico CSI plugin. If not specified, + CSI will be enabled by default. If set to 'None', CSI will be disabled. + Default: /var/lib/kubelet type: string kubernetesProvider: - description: KubernetesProvider specifies a particular provider - of the Kubernetes platform and enables provider-specific configuration. - If the specified value is empty, the Operator will attempt to - automatically determine the current provider. If the specified - value is not empty, the Operator will still attempt auto-detection, - but will additionally compare the auto-detected value to the - specified value to confirm they match. + description: |- + KubernetesProvider specifies a particular provider of the Kubernetes platform and enables provider-specific configuration. + If the specified value is empty, the Operator will attempt to automatically determine the current provider. + If the specified value is not empty, the Operator will still attempt auto-detection, but + will additionally compare the auto-detected value to the specified value to confirm they match. enum: - "" - EKS @@ -22841,71 +20199,68 @@ spec: type: object type: object nodeMetricsPort: - description: NodeMetricsPort specifies which port calico/node - serves prometheus metrics on. By default, metrics are not enabled. - If specified, this overrides any FelixConfiguration resources - which may exist. If omitted, then prometheus metrics may still - be configured through FelixConfiguration. + description: |- + NodeMetricsPort specifies which port calico/node serves prometheus metrics on. By default, metrics are not enabled. + If specified, this overrides any FelixConfiguration resources which may exist. If omitted, then + prometheus metrics may still be configured through FelixConfiguration. format: int32 type: integer nodeUpdateStrategy: - description: NodeUpdateStrategy can be used to customize the desired - update strategy, such as the MaxUnavailable field. + description: |- + NodeUpdateStrategy can be used to customize the desired update strategy, such as the MaxUnavailable + field. properties: rollingUpdate: - description: 'Rolling update config params. Present only if - type = "RollingUpdate". --- TODO: Update this to follow - our convention for oneOf, whatever we decide it to be. Same - as Deployment `strategy.rollingUpdate`. See https://github.com/kubernetes/kubernetes/issues/35345' + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of nodes with an existing - available DaemonSet pod that can have an updated DaemonSet - pod during during an update. Value can be an absolute - number (ex: 5) or a percentage of desired pods (ex: - 10%). This can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding up - to a minimum of 1. Default value is 0. Example: when - this is set to 30%, at most 30% of the total number - of nodes that should be running the daemon pod (i.e. - status.desiredNumberScheduled) can have their a new - pod created before the old pod is marked as deleted. - The update starts by launching new pods on 30% of nodes. - Once an updated pod is available (Ready for at least - minReadySeconds) the old DaemonSet pod on that node - is marked deleted. If the old pod becomes unavailable - for any reason (Ready transitions to false, is evicted, - or is drained) an updated pod is immediatedly created - on that node without considering surge limits. Allowing - surge implies the possibility that the resources consumed - by the daemonset on any given node can double if the - readiness check fails, and so resource intensive daemonsets - should take into account that they may cause evictions - during disruption.' + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of DaemonSet pods that - can be unavailable during the update. Value can be an - absolute number (ex: 5) or a percentage of total number - of DaemonSet pods at the start of the update (ex: 10%). - Absolute number is calculated from percentage by rounding - up. This cannot be 0 if MaxSurge is 0 Default value - is 1. Example: when this is set to 30%, at most 30% - of the total number of nodes that should be running - the daemon pod (i.e. status.desiredNumberScheduled) - can have their pods stopped for an update at any given - time. The update starts by stopping at most 30% of those - DaemonSet pods and then brings up new DaemonSet pods - in their place. Once the new pods are available, it - then proceeds onto other DaemonSet pods, thus ensuring - that at least 70% of original number of DaemonSet pods - are available at all times during the update.' + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. x-kubernetes-int-or-string: true type: object type: @@ -22918,15 +20273,14 @@ spec: containers as non-root users where possible. type: string registry: - description: "Registry is the default Docker registry used for - component Docker images. If specified then the given value must - end with a slash character (`/`) and all images will be pulled - from this registry. If not specified then the default registries - will be used. A special case value, UseDefault, is supported - to explicitly specify the default registries will be used. \n - Image format: `/:` - \n This option allows configuring the `` portion of - the above format." + description: |- + Registry is the default Docker registry used for component Docker images. + If specified then the given value must end with a slash character (`/`) and all images will be pulled from this registry. + If not specified then the default registries will be used. A special case value, UseDefault, is + supported to explicitly specify the default registries will be used. + Image format: + `/:` + This option allows configuring the `` portion of the above format. type: string serviceCIDRs: description: Kubernetes Service CIDRs. Specifying this is required @@ -22935,24 +20289,23 @@ spec: type: string type: array typhaAffinity: - description: Deprecated. Please use Installation.Spec.TyphaDeployment - instead. TyphaAffinity allows configuration of node affinity - characteristics for Typha pods. + description: |- + Deprecated. Please use Installation.Spec.TyphaDeployment instead. + TyphaAffinity allows configuration of node affinity characteristics for Typha pods. properties: nodeAffinity: description: NodeAffinity describes node affinity scheduling rules for typha. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -22962,32 +20315,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23000,32 +20347,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23047,63 +20388,53 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: 'WARNING: Please note that if the affinity - requirements specified by this field are not met at - scheduling time, the pod will NOT be scheduled onto - the node. There is no fallback to another affinity rules - with this setting. This may cause networking disruption - or even catastrophic failure! PreferredDuringSchedulingIgnoredDuringExecution - should be used for affinity unless there is a specific - well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution - and you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution - will always have sufficient nodes to satisfy the requirement. - NOTE: RequiredDuringSchedulingIgnoredDuringExecution - is set by default for AKS nodes, to avoid scheduling - Typhas on virtual-nodes. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node.' + description: |- + WARNING: Please note that if the affinity requirements specified by this field are not met at + scheduling time, the pod will NOT be scheduled onto the node. + There is no fallback to another affinity rules with this setting. + This may cause networking disruption or even catastrophic failure! + PreferredDuringSchedulingIgnoredDuringExecution should be used for affinity + unless there is a specific well understood reason to use RequiredDuringSchedulingIgnoredDuringExecution and + you can guarantee that the RequiredDuringSchedulingIgnoredDuringExecution will always have sufficient nodes to satisfy the requirement. + NOTE: RequiredDuringSchedulingIgnoredDuringExecution is set by default for AKS nodes, + to avoid scheduling Typhas on virtual-nodes. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23116,32 +20447,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23160,9 +20485,9 @@ spec: type: object type: object typhaDeployment: - description: TyphaDeployment configures the typha Deployment. - If used in conjunction with the deprecated ComponentResources - or TyphaAffinity, then these overrides take precedence. + description: |- + TyphaDeployment configures the typha Deployment. If used in conjunction with the deprecated + ComponentResources or TyphaAffinity, then these overrides take precedence. properties: metadata: description: Metadata is a subset of a Kubernetes object's @@ -23171,32 +20496,29 @@ spec: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary non-identifying - metadata. Each of these key/value pairs are added to - the object's annotations provided the key does not already - exist in the object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and values - that may match replicaset and service selectors. Each - of these key/value pairs are added to the object's labels - provided the key does not already exist in the object's - labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the specification of the typha Deployment. properties: minReadySeconds: - description: MinReadySeconds is the minimum number of - seconds for which a newly created Deployment pod should - be ready without any of its container crashing, for - it to be considered available. If specified, this overrides - any minReadySeconds value that may be set on the typha - Deployment. If omitted, the typha Deployment will use - its default value for minReadySeconds. + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created Deployment pod should + be ready without any of its container crashing, for it to be considered available. + If specified, this overrides any minReadySeconds value that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for minReadySeconds. format: int32 maximum: 2147483647 minimum: 0 @@ -23206,48 +20528,43 @@ spec: existing pods with new ones. properties: rollingUpdate: - description: Rolling update config params. Present - only if DeploymentStrategyType = RollingUpdate. + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. to be. properties: maxSurge: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be scheduled above the desired number of - pods. Value can be an absolute number (ex: 5) - or a percentage of desired pods (ex: 10%). This - can not be 0 if MaxUnavailable is 0. Absolute - number is calculated from percentage by rounding - up. Defaults to 25%. Example: when this is set - to 30%, the new ReplicaSet can be scaled up - immediately when the rolling update starts, - such that the total number of old and new pods - do not exceed 130% of desired pods. Once old - pods have been killed, new ReplicaSet can be - scaled up further, ensuring that total number - of pods running at any time during the update - is at most 130% of desired pods.' + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. x-kubernetes-int-or-string: true maxUnavailable: anyOf: - type: integer - type: string - description: 'The maximum number of pods that - can be unavailable during the update. Value - can be an absolute number (ex: 5) or a percentage - of desired pods (ex: 10%). Absolute number is - calculated from percentage by rounding down. - This can not be 0 if MaxSurge is 0. Defaults - to 25%. Example: when this is set to 30%, the - old ReplicaSet can be scaled down to 70% of - desired pods immediately when the rolling update - starts. Once new pods are ready, old ReplicaSet - can be scaled down further, followed by scaling - up the new ReplicaSet, ensuring that the total - number of pods available at all times during - the update is at least 70% of desired pods.' + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. x-kubernetes-int-or-string: true type: object type: object @@ -23256,69 +20573,57 @@ spec: that will be created. properties: metadata: - description: Metadata is a subset of a Kubernetes - object's metadata that is added to the pod's metadata. + description: |- + Metadata is a subset of a Kubernetes object's metadata that is added to + the pod's metadata. properties: annotations: additionalProperties: type: string - description: Annotations is a map of arbitrary - non-identifying metadata. Each of these key/value - pairs are added to the object's annotations - provided the key does not already exist in the - object's annotations. + description: |- + Annotations is a map of arbitrary non-identifying metadata. Each of these + key/value pairs are added to the object's annotations provided the key does not + already exist in the object's annotations. type: object labels: additionalProperties: type: string - description: Labels is a map of string keys and - values that may match replicaset and service - selectors. Each of these key/value pairs are - added to the object's labels provided the key - does not already exist in the object's labels. + description: |- + Labels is a map of string keys and values that may match replicaset and + service selectors. Each of these key/value pairs are added to the + object's labels provided the key does not already exist in the object's labels. type: object type: object spec: description: Spec is the typha Deployment's PodSpec. properties: affinity: - description: 'Affinity is a group of affinity - scheduling rules for the typha pods. If specified, - this overrides any affinity that may be set - on the typha Deployment. If omitted, the typha - Deployment will use its default value for affinity. - If used in conjunction with the deprecated TyphaAffinity, - then this value takes precedence. WARNING: Please - note that this field will override the default - calico-typha Deployment affinity.' + description: |- + Affinity is a group of affinity scheduling rules for the typha pods. + If specified, this overrides any affinity that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for affinity. + If used in conjunction with the deprecated TyphaAffinity, then this value takes precedence. + WARNING: Please note that this field will override the default calico-typha Deployment affinity. properties: nodeAffinity: description: Describes node affinity scheduling rules for the pod. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node matches the corresponding - matchExpressions; the node(s) with the - highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling - term matches all objects with implicit - weight 0 (i.e. it's a no-op). A null - preferred scheduling term matches - no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, @@ -23330,11 +20635,9 @@ spec: selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -23342,30 +20645,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23379,11 +20669,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -23391,30 +20679,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23437,36 +20712,30 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to an update), - the system may or may not try to eventually - evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node - selector term matches no objects. - The requirements of them are ANDed. - The TopologySelectorTerm type - implements a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -23474,30 +20743,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23511,11 +20767,9 @@ spec: selector requirements by node's fields. items: - description: A node selector - requirement is a selector - that contains values, a - key, and an operator that - relates the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label @@ -23523,30 +20777,17 @@ spec: applies to. type: string operator: - description: Represents - a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array - of string values. If - the operator is In or - NotIn, the values array - must be non-empty. If - the operator is Exists - or DoesNotExist, the - values array must be - empty. If the operator - is Gt or Lt, the values - array must have a single - element, which will - be interpreted as an - integer. This array - is replaced during a - strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -23569,22 +20810,16 @@ spec: node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the affinity expressions specified by - this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -23607,12 +20842,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -23621,27 +20853,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -23654,33 +20874,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -23688,12 +20895,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -23702,27 +20906,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -23735,55 +20927,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -23793,30 +20966,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -23829,10 +20994,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -23841,24 +21004,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -23871,30 +21025,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -23902,10 +21046,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -23914,24 +21056,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -23944,44 +21077,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -23994,22 +21112,16 @@ spec: same node, zone, etc. as some other pod(s)). properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer - to schedule pods to nodes that satisfy - the anti-affinity expressions specified - by this field, but it may choose a node - that violates one or more of the expressions. - The node that is most preferred is the - one with the greatest sum of weights, - i.e. for each node that meets all of - the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by - iterating through the elements of this - field and adding "weight" to the sum - if the node has pods which matches the - corresponding podAffinityTerm; the node(s) - with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields @@ -24032,12 +21144,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -24046,27 +21155,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -24079,33 +21176,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that - the term applies to. The term - is applied to the union of - the namespaces selected by - this field and the ones listed - in the namespaces field. null - selector and null or empty - namespaces list means "this - pod's namespace". An empty - selector ({}) matches all - namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -24113,12 +21197,9 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, - a key, and an operator - that relates the key - and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is @@ -24127,27 +21208,15 @@ spec: to. type: string operator: - description: operator - represents a key's - relationship to - a set of values. - Valid operators - are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values - is an array of string - values. If the operator - is In or NotIn, - the values array - must be non-empty. - If the operator - is Exists or DoesNotExist, - the values array - must be empty. This - array is replaced - during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -24160,55 +21229,36 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels - is a map of {key,value} - pairs. A single {key,value} - in the matchLabels map - is equivalent to an element - of matchExpressions, whose - key field is "key", the - operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace - names that the term applies - to. The term is applied to - the union of the namespaces - listed in this field and the - ones selected by namespaceSelector. - null or empty namespaces list - and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should - be co-located (affinity) or - not co-located (anti-affinity) - with the pods matching the - labelSelector in the specified - namespaces, where co-located - is defined as running on a - node whose value of the label - with key topologyKey matches - that of any node on which - any of the selected pods is - running. Empty topologyKey - is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with - matching the corresponding podAffinityTerm, + description: |- + weight associated with matching the corresponding podAffinityTerm, in the range 1-100. format: int32 type: integer @@ -24218,30 +21268,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements - specified by this field are not met - at scheduling time, the pod will not - be scheduled onto the node. If the anti-affinity - requirements specified by this field - cease to be met at some point during - pod execution (e.g. due to a pod label - update), the system may or may not try - to eventually evict the pod from its - node. When there are multiple elements, - the lists of nodes corresponding to - each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely - those matching the labelSelector relative - to the given namespace(s)) that this - pod should be co-located (affinity) - or not co-located (anti-affinity) - with, where co-located is defined - as running on a node whose value of - the label with key matches - that of any node on which a pod of - the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over @@ -24254,10 +21296,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -24266,24 +21306,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -24296,30 +21327,20 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaceSelector: - description: A label query over - the set of namespaces that the - term applies to. The term is applied - to the union of the namespaces - selected by this field and the - ones listed in the namespaces - field. null selector and null - or empty namespaces list means - "this pod's namespace". An empty - selector ({}) matches all namespaces. + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. properties: matchExpressions: description: matchExpressions @@ -24327,10 +21348,8 @@ spec: requirements. The requirements are ANDed. items: - description: A label selector - requirement is a selector - that contains values, a - key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -24339,24 +21358,15 @@ spec: applies to. type: string operator: - description: operator - represents a key's relationship - to a set of values. - Valid operators are - In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is - an array of string values. - If the operator is In - or NotIn, the values - array must be non-empty. - If the operator is Exists - or DoesNotExist, the - values array must be - empty. This array is - replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -24369,44 +21379,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is - a map of {key,value} pairs. - A single {key,value} in the - matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", - the operator is "In", and - the values array contains - only "value". The requirements - are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies - a static list of namespace names - that the term applies to. The - term is applied to the union of - the namespaces listed in this - field and the ones selected by - namespaceSelector. null or empty - namespaces list and null namespaceSelector - means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be - co-located (affinity) or not co-located - (anti-affinity) with the pods - matching the labelSelector in - the specified namespaces, where - co-located is defined as running - on a node whose value of the label - with key topologyKey matches that - of any node on which any of the - selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -24415,52 +21410,44 @@ spec: type: object type: object containers: - description: Containers is a list of typha containers. - If specified, this overrides the specified typha - Deployment containers. If omitted, the typha - Deployment will use its default values for its - containers. + description: |- + Containers is a list of typha containers. + If specified, this overrides the specified typha Deployment containers. + If omitted, the typha Deployment will use its default values for its containers. items: description: TyphaDeploymentContainer is a typha Deployment container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment container by name. - Supported values are: calico-typha' + description: |- + Name is an enum which identifies the typha Deployment container by name. + Supported values are: calico-typha enum: - calico-typha type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - container's resources. If omitted, the - typha Deployment will use its default - value for this container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment container's resources. + If omitted, the typha Deployment will use its default value for this container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -24476,9 +21463,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -24487,14 +21474,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -24502,52 +21486,44 @@ spec: type: object type: array initContainers: - description: InitContainers is a list of typha - init containers. If specified, this overrides - the specified typha Deployment init containers. - If omitted, the typha Deployment will use its - default values for its init containers. + description: |- + InitContainers is a list of typha init containers. + If specified, this overrides the specified typha Deployment init containers. + If omitted, the typha Deployment will use its default values for its init containers. items: description: TyphaDeploymentInitContainer is a typha Deployment init container. properties: name: - description: 'Name is an enum which identifies - the typha Deployment init container by - name. Supported values are: typha-certs-key-cert-provisioner' + description: |- + Name is an enum which identifies the typha Deployment init container by name. + Supported values are: typha-certs-key-cert-provisioner enum: - typha-certs-key-cert-provisioner type: string resources: - description: Resources allows customization - of limits and requests for compute resources - such as cpu and memory. If specified, - this overrides the named typha Deployment - init container's resources. If omitted, - the typha Deployment will use its default - value for this init container's resources. - If used in conjunction with the deprecated - ComponentResources, then this value takes - precedence. + description: |- + Resources allows customization of limits and requests for compute resources such as cpu and memory. + If specified, this overrides the named typha Deployment init container's resources. + If omitted, the typha Deployment will use its default value for this init container's resources. + If used in conjunction with the deprecated ComponentResources, then this value takes precedence. properties: claims: - description: "Claims lists the names - of resources, defined in spec.resourceClaims, - that are used by this container. \n - This is an alpha field and requires - enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the - name of one entry in pod.spec.resourceClaims - of the Pod where this field - is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -24563,9 +21539,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -24574,14 +21550,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the - minimum amount of compute resources - required. If Requests is omitted for - a container, it defaults to Limits - if that is explicitly specified, otherwise - to an implementation-defined value. - Requests cannot exceed Limits. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object required: @@ -24591,114 +21564,92 @@ spec: nodeSelector: additionalProperties: type: string - description: 'NodeSelector is the calico-typha - pod''s scheduling constraints. If specified, - each of the key/value pairs are added to the - calico-typha Deployment nodeSelector provided - the key does not already exist in the object''s - nodeSelector. If omitted, the calico-typha Deployment - will use its default value for nodeSelector. - WARNING: Please note that this field will modify - the default calico-typha Deployment nodeSelector.' + description: |- + NodeSelector is the calico-typha pod's scheduling constraints. + If specified, each of the key/value pairs are added to the calico-typha Deployment nodeSelector provided + the key does not already exist in the object's nodeSelector. + If omitted, the calico-typha Deployment will use its default value for nodeSelector. + WARNING: Please note that this field will modify the default calico-typha Deployment nodeSelector. type: object terminationGracePeriodSeconds: - description: Optional duration in seconds the - pod needs to terminate gracefully. May be decreased - in delete request. Value must be non-negative - integer. The value zero indicates stop immediately - via the kill signal (no opportunity to shut - down). If this value is nil, the default grace - period will be used instead. The grace period - is the duration in seconds after the processes - running in the pod are sent a termination signal - and the time when the processes are forcibly - halted with a kill signal. Set this value longer - than the expected cleanup time for your process. + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds. format: int64 type: integer tolerations: - description: 'Tolerations is the typha pod''s - tolerations. If specified, this overrides any - tolerations that may be set on the typha Deployment. - If omitted, the typha Deployment will use its - default value for tolerations. WARNING: Please - note that this field will override the default - calico-typha Deployment tolerations.' + description: |- + Tolerations is the typha pod's tolerations. + If specified, this overrides any tolerations that may be set on the typha Deployment. + If omitted, the typha Deployment will use its default value for tolerations. + WARNING: Please note that this field will override the default calico-typha Deployment tolerations. items: - description: The pod this Toleration is attached - to tolerates any taint that matches the triple - using the matching operator - . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint - effect to match. Empty means match all - taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule - and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the - toleration applies to. Empty means match - all taint keys. If the key is empty, operator - must be Exists; this combination means - to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's - relationship to the value. Valid operators - are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints - of a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents - the period of time the toleration (which - must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. - By default, it is not set, which means - tolerate the taint forever (do not evict). - Zero and negative values will be treated - as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the - toleration matches to. If the operator - is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array topologySpreadConstraints: - description: TopologySpreadConstraints describes - how a group of pods ought to spread across topology - domains. Scheduler will schedule pods in a way - which abides by the constraints. All topologySpreadConstraints - are ANDed. + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. items: description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. properties: labelSelector: - description: LabelSelector is used to find - matching pods. Pods that match this label - selector are counted to determine the - number of pods in their corresponding - topology domain. + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -24706,20 +21657,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -24731,174 +21678,124 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic matchLabelKeys: - description: "MatchLabelKeys is a set of - pod label keys to select the pods over - which spreading will be calculated. The - keys are used to lookup values from the - incoming pod labels, those key-value labels - are ANDed with labelSelector to select - the group of existing pods over which - spreading will be calculated for the incoming - pod. The same key is forbidden to exist - in both MatchLabelKeys and LabelSelector. - MatchLabelKeys cannot be set when LabelSelector - isn't set. Keys that don't exist in the - incoming pod labels will be ignored. A - null or empty list means only match against - labelSelector. \n This is a beta field - and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by - default)." + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). items: type: string type: array x-kubernetes-list-type: atomic maxSkew: - description: 'MaxSkew describes the degree - to which pods may be unevenly distributed. - When `whenUnsatisfiable=DoNotSchedule`, - it is the maximum permitted difference - between the number of matching pods in - the target topology and the global minimum. - The global minimum is the minimum number - of matching pods in an eligible domain - or zero if the number of eligible domains - is less than MinDomains. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 2/2/1: In this case, the global - minimum is 1. | zone1 | zone2 | zone3 - | | P P | P P | P | - if MaxSkew - is 1, incoming pod can only be scheduled - to zone3 to become 2/2/2; scheduling it - onto zone1(zone2) would make the ActualSkew(3-1) - on zone1(zone2) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled - onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to - topologies that satisfy it. It''s a required - field. Default value is 1 and 0 is not - allowed.' + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. format: int32 type: integer minDomains: - description: "MinDomains indicates a minimum - number of eligible domains. When the number - of eligible domains with matching topology - keys is less than minDomains, Pod Topology - Spread treats \"global minimum\" as 0, - and then the calculation of Skew is performed. - And when the number of eligible domains - with matching topology keys equals or - greater than minDomains, this value has - no effect on scheduling. As a result, - when the number of eligible domains is - less than minDomains, scheduler won't - schedule more than maxSkew Pods to those - domains. If value is nil, the constraint - behaves as if MinDomains is equal to 1. - Valid values are integers greater than - 0. When value is not nil, WhenUnsatisfiable - must be DoNotSchedule. \n For example, - in a 3-zone cluster, MaxSkew is set to - 2, MinDomains is set to 5 and pods with - the same labelSelector spread as 2/2/2: - | zone1 | zone2 | zone3 | | P P | P - P | P P | The number of domains is - less than 5(MinDomains), so \"global minimum\" - is treated as 0. In this situation, new - pod with the same labelSelector cannot - be scheduled, because computed skew will - be 3(3 - 0) if new Pod is scheduled to - any of the three zones, it will violate - MaxSkew. \n This is a beta field and requires - the MinDomainsInPodTopologySpread feature - gate to be enabled (enabled by default)." + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates - how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew. - Options are: - Honor: only nodes matching - nodeAffinity/nodeSelector are included - in the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in - the calculations. \n If this value is - nil, the behavior is equivalent to the - Honor policy. This is a beta-level feature - default enabled by the NodeInclusionPolicyInPodTopologySpread - feature flag." + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates - how we will treat node taints when calculating + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - - Honor: nodes without taints, along with - tainted nodes for which the incoming pod - has a toleration, are included. - Ignore: - node taints are ignored. All nodes are - included. \n If this value is nil, the - behavior is equivalent to the Ignore policy. - This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread - feature flag." + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. type: string topologyKey: - description: TopologyKey is the key of node - labels. Nodes that have a label with this - key and identical values are considered - to be in the same topology. We consider - each as a "bucket", and try - to put balanced number of pods into each - bucket. We define a domain as a particular - instance of a topology. Also, we define - an eligible domain as a domain whose nodes - meet the requirements of nodeAffinityPolicy - and nodeTaintsPolicy. e.g. If TopologyKey - is "kubernetes.io/hostname", each Node - is a domain of that topology. And, if - TopologyKey is "topology.kubernetes.io/zone", - each zone is a domain of that topology. + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. type: string whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates - how to deal with a pod if it doesn''t - satisfy the spread constraint. - DoNotSchedule - (default) tells the scheduler not to schedule - it. - ScheduleAnyway tells the scheduler - to schedule the pod in any location, but - giving higher precedence to topologies - that would help reduce the skew. A constraint - is considered "Unsatisfiable" for an incoming - pod if and only if every possible node - assignment for that pod would violate - "MaxSkew" on some topology. For example, - in a 3-zone cluster, MaxSkew is set to - 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 - | | P P P | P | P | If WhenUnsatisfiable - is set to DoNotSchedule, incoming pod - can only be scheduled to zone2(zone3) - to become 3/2/1(3/1/2) as ActualSkew(2-1) - on zone2(zone3) satisfies MaxSkew(1). - In other words, the cluster can still - be imbalanced, but scheduler won''t make - it *more* imbalanced. It''s a required - field.' + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. type: string required: - maxSkew @@ -24916,8 +21813,9 @@ spec: format: int32 type: integer variant: - description: 'Variant is the product to install - one of Calico - or TigeraSecureEnterprise Default: Calico' + description: |- + Variant is the product to install - one of Calico or TigeraSecureEnterprise + Default: Calico enum: - Calico - TigeraSecureEnterprise @@ -24926,15 +21824,19 @@ spec: description: Windows Configuration properties: cniBinDir: - description: CNIBinDir is the path to the CNI binaries directory - on Windows, it must match what is used as 'bin_dir' under - [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIBinDir is the path to the CNI binaries directory on Windows, it must match what is used as 'bin_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniConfigDir: - description: CNIConfigDir is the path to the CNI configuration - directory on Windows, it must match what is used as 'conf_dir' - under [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".cni] + description: |- + CNIConfigDir is the path to the CNI configuration directory on Windows, it must match what is used as 'conf_dir' under + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + [plugins."io.containerd.grpc.v1.cri".cni] on the containerd 'config.toml' file on the Windows nodes. type: string cniLogDir: @@ -24953,47 +21855,47 @@ spec: type: object type: object conditions: - description: Conditions represents the latest observed set of conditions - for the component. A component may be one or more of Ready, Progressing, - Degraded or other customer types. + description: |- + Conditions represents the latest observed set of conditions for the component. A component may be one or more of + Ready, Progressing, Degraded or other customer types. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -25007,11 +21909,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -25024,14 +21927,14 @@ spec: type: object type: array imageSet: - description: ImageSet is the name of the ImageSet being used, if there - is an ImageSet that is being used. If an ImageSet is not being used - then this will not be set. + description: |- + ImageSet is the name of the ImageSet being used, if there is an ImageSet + that is being used. If an ImageSet is not being used then this will not be set. type: string mtu: - description: MTU is the most recently observed value for pod network - MTU. This may be an explicitly configured value, or based on Calico's - native auto-detetion. + description: |- + MTU is the most recently observed value for pod network MTU. This may be an explicitly + configured value, or based on Calico's native auto-detetion. format: int32 type: integer variant: @@ -25054,7 +21957,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.3 + controller-gen.kubebuilder.io/version: v0.14.0 name: tigerastatuses.operator.tigera.io spec: group: operator.tigera.io @@ -25089,14 +21992,19 @@ spec: Calico or a Calico Enterprise functional area. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -25107,9 +22015,9 @@ spec: description: TigeraStatusStatus defines the observed state of TigeraStatus properties: conditions: - description: Conditions represents the latest observed set of conditions - for this component. A component may be one or more of Available, - Progressing, or Degraded. + description: |- + Conditions represents the latest observed set of conditions for this component. A component may be one or more of + Available, Progressing, or Degraded. items: description: TigeraStatusCondition represents a condition attached to a particular component. @@ -25124,11 +22032,10 @@ spec: context. type: string observedGeneration: - description: observedGeneration represents the generation that - the condition was set based upon. For instance, if generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the generation that the condition was set based upon. + For instance, if generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 type: integer reason: @@ -25386,6 +22293,12 @@ rules: - watch - create - update + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - delete # Needed for operator lock - apiGroups: - coordination.k8s.io @@ -25437,6 +22350,41 @@ rules: - create - update - delete + # For tiered network policy actions, tigera-apiserver requires that we authorize the operator for the tier.networkpolicies and tier.globalnetworkpolicies pseudo-kinds. + - apiGroups: + - projectcalico.org + resourceNames: + - allow-tigera.* + resources: + - tier.networkpolicies + - tier.globalnetworkpolicies + verbs: + - list + - watch + - get + - create + - update + - delete + # For tiered network policy actions, tigera-apiserver requires get authorization on the associated tier. + - apiGroups: + - projectcalico.org + resourceNames: + - allow-tigera + resources: + - tiers + verbs: + - get + - delete + - update + # Separated from the above rule since resourceNames does not support the create verb, and requires a field selector for list/watch verbs. + - apiGroups: + - projectcalico.org + resources: + - tiers + verbs: + - create + - list + - watch --- # Source: tigera-operator/templates/tigera-operator/02-rolebinding-tigera-operator.yaml kind: ClusterRoleBinding diff --git a/metadata.mk b/metadata.mk index a2e411bec6c..83297a2a252 100644 --- a/metadata.mk +++ b/metadata.mk @@ -3,19 +3,19 @@ ################################################################################################# # The version of github.com/projectcalico/go-build to use. -GO_BUILD_VER=v0.91 +GO_BUILD_VER=v0.93 # Env var to ACK Ginkgo deprecation warnings, may need updating with go-build. ACK_GINKGO=ACK_GINKGO_DEPRECATIONS=1.16.5 # Version of Kubernetes to use for tests, bitnami/kubectl, and kubectl binary release. -K8S_VERSION=v1.28.7 +K8S_VERSION=v1.29.9 # Version of various tools used in the build and tests. COREDNS_VERSION=1.5.2 ETCD_VERSION=v3.5.6 HELM_VERSION=v3.11.3 -KINDEST_NODE_VERSION=v1.27.11 -KIND_VERSION=v0.22.0 +KINDEST_NODE_VERSION=v1.29.8 +KIND_VERSION=v0.24.0 PROTOC_VER=v0.1 UBI_VERSION=8.10 @@ -33,11 +33,6 @@ BIRD_VERSION=v0.3.3-211-g9111ec3c # as both CI/CD and the release tooling will override this to build publishable images. DEV_REGISTRIES ?= calico -# RELEASE_REGISTRIES configures the container images registries which are published to -# as part of an official release. -# This variable is unused. Registries for releases are defined in hack/release/pkg/builder/builder.go -# RELEASE_REGISTRIES = quay.io/calico docker.io/calico gcr.io/projectcalico-org eu.gcr.io/projectcalico-org asia.gcr.io/projectcalico-org us.gcr.io/projectcalico-org - # The directory for windows image tarballs WINDOWS_DIST = dist/windows diff --git a/node/calico_test/requirements.txt b/node/calico_test/requirements.txt index 2a28c20fc1a..19d72689cec 100644 --- a/node/calico_test/requirements.txt +++ b/node/calico_test/requirements.txt @@ -9,7 +9,6 @@ deepdiff==3.3.0 enum34==1.1.10 funcsigs==1.0.2 google-auth==2.18.1 -idna==2.10 importlib-metadata==2.1.3 ipaddress==1.0.23 jsonpickle==2.2.0 @@ -38,4 +37,3 @@ typing==3.10.0.0 urllib3==1.26.19 wcwidth==0.2.13 websocket-client==0.59.0 -zipp==1.2.0 \ No newline at end of file diff --git a/node/cmd/calico-node/main.go b/node/cmd/calico-node/main.go index 1fac3754d2f..72d151323d0 100644 --- a/node/cmd/calico-node/main.go +++ b/node/cmd/calico-node/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + package main import ( @@ -86,8 +87,8 @@ func main() { // fluentd's default configuration. logrus.SetOutput(os.Stdout) - // Install a hook that adds file/line no information. - logrus.AddHook(&logutils.ContextHook{}) + // Set up logging formatting. + logutils.ConfigureFormatter("node") // Parse the provided flags. err := flagSet.Parse(os.Args[1:]) diff --git a/node/pkg/allocateip/allocateip_test.go b/node/pkg/allocateip/allocateip_test.go index 4385bb1f0c5..4b67e119195 100644 --- a/node/pkg/allocateip/allocateip_test.go +++ b/node/pkg/allocateip/allocateip_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018,2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2018-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -1567,3 +1567,7 @@ func (c shimClient) BlockAffinities() client.BlockAffinityInterface { func (c shimClient) EnsureInitialized(ctx context.Context, calicoVersion, clusterType string) error { return nil } + +func (c shimClient) Tiers() client.TierInterface { + panic("not implemented") +} diff --git a/node/pkg/health/health.go b/node/pkg/health/health.go index 083ccd40879..82faa3ab3fc 100644 --- a/node/pkg/health/health.go +++ b/node/pkg/health/health.go @@ -164,7 +164,7 @@ func checkService(serviceName string) error { cmdOutput := string(out) if !strings.HasPrefix(cmdOutput, "run") { - return fmt.Errorf(fmt.Sprintf("Service %s is not running. Output << %s >>", serviceName, strings.Trim(cmdOutput, "\n"))) + return fmt.Errorf("Service %s is not running. Output << %s >>", serviceName, strings.Trim(cmdOutput, "\n")) } return nil diff --git a/node/tests/k8st/infra/apiserver.yaml b/node/tests/k8st/infra/apiserver.yaml index d09d290fa29..cab751305ab 100644 --- a/node/tests/k8st/infra/apiserver.yaml +++ b/node/tests/k8st/infra/apiserver.yaml @@ -160,6 +160,7 @@ rules: - apiGroups: - crd.projectcalico.org resources: + - tiers - globalnetworkpolicies - networkpolicies - clusterinformations @@ -221,6 +222,15 @@ rules: - get - list - watch +- apiGroups: + - flowcontrol.apiserver.k8s.io + resources: + - flowschemas + - prioritylevelconfigurations + verbs: + - get + - list + - watch --- @@ -298,3 +308,30 @@ subjects: - kind: ServiceAccount name: calico-apiserver namespace: calico-apiserver + +--- + +# Needed for kube-controller-manager to function. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: tigera-getter +rules: +- apiGroups: ["projectcalico.org"] + resources: ["tiers"] + verbs: ["get"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: tigera-getter +roleRef: + kind: ClusterRole + name: tigera-getter + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: User + name: "system:kube-controller-manager" + apiGroup: rbac.authorization.k8s.io diff --git a/node/tests/k8st/infra/calico-kdd.yaml b/node/tests/k8st/infra/calico-kdd.yaml index a606787a1c0..4f56e86ce69 100644 --- a/node/tests/k8st/infra/calico-kdd.yaml +++ b/node/tests/k8st/infra/calico-kdd.yaml @@ -125,6 +125,7 @@ rules: - blockaffinities - ipamblocks - ipamhandles + - tiers verbs: - get - list @@ -236,6 +237,13 @@ rules: verbs: - watch - list + # Watch for changes to Kubernetes AdminNetworkPolicies. + - apiGroups: ["policy.networking.k8s.io"] + resources: + - adminnetworkpolicies + verbs: + - watch + - list # Used by Calico for policy information. - apiGroups: [""] resources: @@ -271,6 +279,7 @@ rules: - hostendpoints - blockaffinities - caliconodestatuses + - tiers verbs: - get - list diff --git a/node/tests/k8st/infra/calicoctl.yaml b/node/tests/k8st/infra/calicoctl.yaml index b93933e2b9e..fe5289543a8 100644 --- a/node/tests/k8st/infra/calicoctl.yaml +++ b/node/tests/k8st/infra/calicoctl.yaml @@ -87,6 +87,7 @@ rules: - ipamblocks - blockaffinities - ipamhandles + - tiers verbs: - create - get diff --git a/node/tests/st/policy/test_tiered_policy.py b/node/tests/st/policy/test_tiered_policy.py new file mode 100644 index 00000000000..6844e821518 --- /dev/null +++ b/node/tests/st/policy/test_tiered_policy.py @@ -0,0 +1,927 @@ +# Copyright 2024 Tigera, Inc + +import copy +import functools +import json +import logging +import subprocess +import time +import yaml +from nose_parameterized import parameterized +from multiprocessing.dummy import Pool + +from tests.st.test_base import TestBase, HOST_IPV4 +from tests.st.utils.docker_host import DockerHost +from tests.st.utils.utils import assert_number_endpoints, get_ip, \ + ETCD_CA, ETCD_CERT, ETCD_KEY, ETCD_HOSTNAME_SSL, ETCD_SCHEME, \ + wipe_etcd + +_log = logging.getLogger(__name__) +_log.setLevel(logging.DEBUG) + +POST_DOCKER_COMMANDS = ["docker load -i /code/calico-node.tar", + "docker load -i /code/busybox.tar", + "docker load -i /code/workload.tar"] + +if ETCD_SCHEME == "https": + ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " \ + "--cluster-store-opt kv.cacertfile=%s " \ + "--cluster-store-opt kv.certfile=%s " \ + "--cluster-store-opt kv.keyfile=%s " % \ + (ETCD_HOSTNAME_SSL, ETCD_CA, ETCD_CERT, + ETCD_KEY) +else: + ADDITIONAL_DOCKER_OPTIONS = "--cluster-store=etcd://%s:2379 " % \ + get_ip() + + +def parallel_host_setup(num_hosts): + makehost = functools.partial(DockerHost, + additional_docker_options=ADDITIONAL_DOCKER_OPTIONS, + post_docker_commands=POST_DOCKER_COMMANDS, + start_calico=False) + hostnames = [] + for i in range(num_hosts): + hostnames.append("host%s" % i) + pool = Pool(num_hosts) + hosts = pool.map(makehost, hostnames) + pool.close() + pool.join() + return hosts + + +gnp_next_all = { + "apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "gnp_next_all"}, + "spec": { + "order": 10, + "ingress": [{"action": "Pass"}], + "egress": [{"action": "Pass"}] + } +} + +gnp_allow_all = { + "apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "gnp_allow_all"}, + "spec": { + "order": 10, + "ingress": [{"action": "Allow"}], + "egress": [{"action": "Allow"}] + } +} + +gnp_deny_all = { + "apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "gnp_deny_all"}, + "spec": { + "order": 10, + "ingress": [{"action": "Deny"}], + "egress": [{"action": "Deny"}]} +} +gnp_none_all = { + "apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "gnp_none_all"}, + "spec": { + "selector": "all()", + "order": 10, + "ingress": [], + "egress": []} +} + + +class TieredPolicyWorkloads(TestBase): + def setUp(self): + _log.debug("Override the TestBase setUp() method which wipes etcd. Do nothing.") + # Wipe policies and tiers before each test + self.delete_all("gnp") + self.delete_all("tier") + + def delete_all(self, resource): + # Grab all objects of a resource type + objects = yaml.load(self.hosts[0].calicoctl("get %s -o yaml" % resource)) + # and delete them (if there are any) + if len(objects) > 0: + _log.info("objects: %s", objects) + if 'items' in objects: + # Filter out object(s) representing the default tier. + objects['items'] = [x for x in objects['items'] + if (x.get('kind', '') != 'Tier' or + 'metadata' not in x or + x['metadata'].get('name', '') not in ['default', 'adminnetworkpolicy'])] + if 'items' in objects and len(objects['items']) == 0: + pass + else: + self._delete_data(objects, self.hosts[0]) + + @staticmethod + def sleep(length): + _log.debug("Sleeping for %s" % length) + time.sleep(length) + + @classmethod + def setUpClass(cls): + _log.debug("Wiping etcd") + wipe_etcd(HOST_IPV4) + + cls.policy_tier_name = "default" + cls.next_tier_allowed = False + cls.hosts = [] + cls.hosts.append(DockerHost("host1", + additional_docker_options=ADDITIONAL_DOCKER_OPTIONS, + post_docker_commands=POST_DOCKER_COMMANDS, + start_calico=False)) + cls.hosts.append(DockerHost("host2", + additional_docker_options=ADDITIONAL_DOCKER_OPTIONS, + post_docker_commands=POST_DOCKER_COMMANDS, + start_calico=False)) + + for host in cls.hosts: + host.start_calico_node() + # Allow time for calico-node to load + time.sleep(10) + + cls.networks = [] + cls.networks.append(cls.hosts[0].create_network("testnet2")) + cls.sleep(10) + + cls.n1_workloads = [] + # Create two workloads on cls.hosts[0] and one on cls.hosts[1] all in network 1. + cls.n1_workloads.append(cls.hosts[1].create_workload("workload_h2n1_1", + image="workload", + network=cls.networks[0])) + cls.sleep(2) + cls.n1_workloads.append(cls.hosts[0].create_workload("workload_h1n1_1", + image="workload", + network=cls.networks[0])) + # Assert that endpoints are in Calico + assert_number_endpoints(cls.hosts[0], 1) + assert_number_endpoints(cls.hosts[1], 1) + + @classmethod + def tearDownClass(cls): + # Tidy up + for host in cls.hosts: + host.remove_workloads() + for network in cls.networks: + network.delete() + for host in cls.hosts: + host.cleanup() + del host + + def test_tier_ordering_explicit(self): + """Check correct ordering of tiers by their explicit order field.""" + self.policy_tier_name = "the-tier" + self.next_tier_allowed = True + self._do_tier_order_test("tier-c", 1, + "tier-b", 2, + "tier-a", 3) + + def test_tier_ordering_implicit(self): + """Check correct ordering of tiers by name as tie-breaker.""" + self.policy_tier_name = "the-tier" + self.next_tier_allowed = True + self._do_tier_order_test("tier-1", 1, + "tier-2", 1, + "tier-3", 1) + + def set_tier(self, name=None, order=10): + _log.debug("Setting tier data: \n" + "name : %s\norder : %s", + name, order) + if name is None: + name = self.policy_tier_name + tier = {"apiVersion": "projectcalico.org/v3", + "kind": "Tier", + "metadata": {"name": name}, + "spec": {"order": order} + } + self._apply_data(tier, self.hosts[0]) + + def _do_tier_order_test(self, first_tier, first_tier_order, second_tier, + second_tier_order, third_tier, third_tier_order): + # Note that the following tests need to check that connectivity to + # the rpcbind service alternates between succeeding and failing so + # that we spot if felix hasn't actually changed anything. + # Check we start with connectivity. + _log.info("Starting tier order test %s (%s); %s (%s); %s (%s)", + first_tier, first_tier_order, second_tier, + second_tier_order, third_tier, third_tier_order) + + self.assert_connectivity(self.n1_workloads) + + # Create tiers and endpoints. + _log.info("Configuring tiers.") + self.set_tier(name=first_tier, order=first_tier_order) + self.set_tier(name=second_tier, order=second_tier_order) + self.set_tier(name=third_tier, order=third_tier_order) + + # Slip a deny into the third tier, just to alternate DENY/ALLOW. + self.set_policy(third_tier, "pol-1", gnp_deny_all) + # Check that access is blocked. + self.assert_no_connectivity(self.n1_workloads) + + # Allow in first tier only, should allow. + _log.info("Allow in first tier only, should allow.") + self.set_policy(first_tier, "pol-1", gnp_allow_all) + self.set_policy(second_tier, "pol-1", gnp_deny_all) + self.set_policy(third_tier, "pol-1", gnp_deny_all) + self.assert_connectivity(self.n1_workloads) + + # Deny in all tiers, should drop. + _log.info("Deny in all tiers, should drop.") + # Fix up second tier + self.set_policy(second_tier, "pol-1", gnp_deny_all) + self.set_policy(first_tier, "pol-1", gnp_deny_all) + self.assert_no_connectivity(self.n1_workloads) + + # Allow in first tier, should allow. + self.set_policy(first_tier, "pol-1", gnp_allow_all) + self.assert_connectivity(self.n1_workloads) + + # Switch, now the first tier drops but the later ones allow. + _log.info("Switch, now the first tier drops but the later ones " + "allow.") + self.set_policy(first_tier, "pol-1", gnp_deny_all) + self.set_policy(second_tier, "pol-1", gnp_allow_all) + self.set_policy(third_tier, "pol-1", gnp_allow_all) + self.assert_no_connectivity(self.n1_workloads) + + # Fall through via a next-tier policy in the first tier. + _log.info("Fall through via a next-tier policy in the first " + "tier.") + self.set_policy(first_tier, "pol-1", gnp_next_all) + self.assert_connectivity(self.n1_workloads) + + # Swap the second tier for a drop. + _log.info("Swap the second tier for a drop.") + self.set_policy(second_tier, "pol-1", gnp_deny_all) + self.assert_no_connectivity(self.n1_workloads) + + def _apply_data(self, data, host): + _log.debug("Applying data with calicoctl: %s", data) + self._use_calicoctl("apply", data, host) + + def _delete_data(self, data, host): + _log.debug("Deleting data with calicoctl: %s", data) + self._use_calicoctl("delete", data, host) + + @staticmethod + def _use_calicoctl(action, data, host): + # Delete creationTimestamp fields from the data that we're going to + # write. + _log.debug("Use calicoctl: %s", data) + if type(data) == list: + for d in data: + for obj in d.get('items', []): + if 'creationTimestamp' in obj['metadata']: + del obj['metadata']['creationTimestamp'] + if 'metadata' in data and 'creationTimestamp' in data['metadata']: + del data['metadata']['creationTimestamp'] + else: + for obj in data.get('items', []): + if 'creationTimestamp' in obj['metadata']: + del obj['metadata']['creationTimestamp'] + if 'metadata' in data and 'creationTimestamp' in data['metadata']: + del data['metadata']['creationTimestamp'] + + # use calicoctl with data + host.writefile("new_data", + yaml.dump(data, default_flow_style=False)) + host.calicoctl("%s -f new_data" % action) + + def set_policy(self, tier, policy_name, data, order=None): + data = copy.deepcopy(data) + if order is not None: + data["spec"]["order"] = order + + if not self.next_tier_allowed: + for dirn in ["ingress", "egress"]: + if dirn in data: + def f(rule): + return rule != {"action": "Pass"} + data[dirn] = filter(f, data[dirn]) + + data["metadata"]["name"] = policy_name + if tier != "default": + data["spec"]["tier"] = tier + data["metadata"]["name"] = "{tier}.{policy}".format(tier=tier, + policy=data["metadata"]["name"]) + elif tier == "default": + # TODO(doublek): This elif can be removed when proper tier + # validation has been added. + data["spec"]["tier"] = "default" + data["metadata"]["name"] = "default.{policy}".format(policy=data["metadata"]["name"]) + + self._apply_data(data, self.hosts[0]) + + def assert_no_connectivity(self, workload_list, retries=0, type_list=None): + """ + Checks that none of the workloads passed in can contact any of the others. + :param workload_list: + :param retries: + :param type_list: + :return: + """ + for workload in workload_list: + the_rest = [wl for wl in workload_list if wl is not workload] + self.assert_connectivity([workload], fail_list=the_rest, + retries=retries, type_list=type_list) + + def test_policy_ordering_explicit(self): + """Check correct ordering of policies by their explicit order + field.""" + self.policy_tier_name = "default" + self.next_tier_allowed = False + self._do_policy_order_test("pol-c", 1, + "pol-b", 2, + "pol-a", 3) + + def test_policy_ordering_implicit(self): + """Check correct ordering of policies by name as tie-breaker.""" + self.policy_tier_name = "default" + self.next_tier_allowed = False + self._do_policy_order_test("pol-1", 1, + "pol-2", 1, + "pol-3", 1) + + def _do_policy_order_test(self, + first_pol, first_pol_order, + second_pol, second_pol_order, + third_pol, third_pol_order): + """Checks that policies are ordered correctly.""" + # Note that the following tests need to check that connectivity to + # the rpcbind service alternates between succeeding and failing so + # that we spot if felix hasn't actually changed anything. + + _log.info("Check we start with connectivity.") + self.assert_connectivity(self.n1_workloads) + _log.info("Apply a single deny policy") + self.set_policy(self.policy_tier_name, first_pol, gnp_deny_all, + order=first_pol_order) + _log.info("Check we now cannot access tcp service") + self.assert_no_connectivity(self.n1_workloads) + _log.info("Allow in first tier only, should allow.") + self.set_policy(self.policy_tier_name, first_pol, gnp_allow_all, + order=first_pol_order) + self.set_policy(self.policy_tier_name, second_pol, gnp_deny_all, + order=second_pol_order) + self.set_policy(self.policy_tier_name, third_pol, gnp_deny_all, + order=third_pol_order) + self.assert_connectivity(self.n1_workloads) + + # Fix up second tier + self.set_policy(self.policy_tier_name, second_pol, gnp_deny_all, + order=second_pol_order) + + # Deny in all tiers, should drop. + _log.info("Deny in all tiers, should drop.") + self.set_policy(self.policy_tier_name, first_pol, gnp_deny_all, + order=first_pol_order) + self.assert_no_connectivity(self.n1_workloads) + + # Allow in first tier, should allow. + _log.info("Allow in first tier, should allow.") + self.set_policy(self.policy_tier_name, first_pol, gnp_allow_all, + order=first_pol_order) + self.assert_connectivity(self.n1_workloads) + + # Switch, now the first policy drops but the later ones allow. + _log.info("Switch, now the first tier drops but the later ones " + "allow.") + self.set_policy(self.policy_tier_name, first_pol, gnp_deny_all, + order=first_pol_order) + self.set_policy(self.policy_tier_name, second_pol, gnp_allow_all, + order=second_pol_order) + self.set_policy(self.policy_tier_name, third_pol, gnp_allow_all, + order=third_pol_order) + self.assert_no_connectivity(self.n1_workloads) + + # Fall through to second policy. + _log.info("Fall through to second policy.") + self.set_policy(self.policy_tier_name, first_pol, gnp_none_all, + order=first_pol_order) + self.assert_connectivity(self.n1_workloads) + + # Swap the second tier for a drop. + _log.info("Swap the second tier for a drop.") + self.set_policy(self.policy_tier_name, second_pol, gnp_deny_all, + order=second_pol_order) + self.assert_no_connectivity(self.n1_workloads) + + @parameterized.expand([ + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true1"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "test == 'True'"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "test == 'True'"}}, + {"action": "Allow"} + ]}, + }, + {"test": "True"}, + True + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true2"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "test != 'True'"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "test != 'True'"}}, + {"action": "Allow"} + ]}, + }, + {"test": "False"}, + False + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true3"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "has(test)"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "has(test)"}}, + {"action": "Allow"} + ]}, + }, + {"test": "any_old_value"}, + True + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true4"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "!has(test)"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "!has(test)"}}, + {"action": "Allow"} + ]}, + }, + {"test": "no_one_cares"}, + False + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true5"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "test in {'true', 'false'}"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "test in {'true', 'false'}"}}, + {"action": "Allow"} + ]}, + }, + {"test": "true"}, + True + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true6"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "test in {'true', 'false'}"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "test in {'true', 'false'}"}}, + {"action": "Allow"} + ]}, + }, + {"test": "false"}, + True + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true7"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": {"selector": "test not in {'true', 'false'}"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": {"selector": "test not in {'true', 'false'}"}}, + {"action": "Allow"} + ]}, + }, + {"test": "neither"}, + False + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true8a"}, + "spec": + { + "tier": "default", + "selector": "test == 'true'", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true8b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "true"}, + True + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true9a"}, + "spec": + { + "tier": "default", + "selector": "test != 'true'", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true9b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "true"}, + False + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true10a"}, + "spec": + { + "tier": "default", + "selector": "has(test)", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true10b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "true"}, + True + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true11a"}, + "spec": + { + "tier": "default", + "selector": "!has(test)", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true11b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "true"}, + False + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true12a"}, + "spec": + { + "tier": "default", + "selector": "test in {'true', 'false'}", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true12b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "true"}, + True + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true13a"}, + "spec": + { + "tier": "default", + "selector": "test in {'true', 'false'}", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true13b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "false"}, + True + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true14a"}, + "spec": + { + "tier": "default", + "selector": "test not in {'true', 'false'}", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true14b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "neither"}, + False + ), + + ([{"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true15a"}, + "spec": + { + "tier": "default", + "selector": "has(test) && test in {'true', 'false'} && test == 'true'", + "ingress": [ + {"action": "Deny"}, + ], + "egress": [ + {"action": "Deny"}, + ] + } + }, + {"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true15b"}, + "spec": + { + "tier": "default", + "ingress": [ + {"action": "Allow"}, + ], + "egress": [ + {"action": "Allow"}, + ] + } + } + ], + {"test": "true"}, + True + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true16"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": + {"selector": "has(test) && test in {'True', 'False'} && test == 'True'"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": + {"selector": "has(test) && test in {'True', 'False'} && test == 'True'"}}, + {"action": "Allow"} + ]}, + }, + {"test": "True"}, + True + ), + + ({"apiVersion": "projectcalico.org/v3", + "kind": "GlobalNetworkPolicy", + "metadata": {"name": "default.deny-test-true17"}, + "spec": { + "tier": "default", + "ingress": [{ + "action": "Deny", + "source": + {"selector": + "has(test) && test not in {'True', 'False'} && test == 'Sausage'"}, + }, + {"action": "Allow"} + ], + "egress": [ + {"action": "Deny", + "destination": + {"selector": + "has(test) && test not in {'True', 'False'} && test == 'Sausage'"}}, + {"action": "Allow"} + ]}, + }, + {"test": "Sausage"}, + True + ), + ]) + def test_selectors(self, policy, workload_label, no_label_expected_result): + """ + Tests selectors in policy. + :param policy: The policy to apply + :param workload_label: The label to add to one of the workload endpoints + :param no_label_expected_result: Whether we'd expect the policy to block connectivity if + the workloads do not have the label. + :return: + """ + # set workload config + host = self.hosts[0] + weps = yaml.safe_load(host.calicoctl("get wep -o yaml")) + _log.info("n1_workloads 0 %s", self.n1_workloads[0].__dict__) + _log.info("n1_workloads 1 %s", self.n1_workloads[1].__dict__) + wep_old = weps['items'][0] + #for w in weps['items']: + # if w['spec']['ipNetworks'][0] == self.n1_workloads[1].ip + '/32': + # _log.info("Set wep_old to %s", w) + # wep_old = w + wep = copy.deepcopy(wep_old) + _log.info("Set new label %s", workload_label) + wep['metadata']['labels'] = workload_label + self._apply_data(wep, host) + updated_weps = yaml.safe_load(host.calicoctl("get workloadEndpoint -o yaml")) + # check connectivity OK + self.assert_connectivity(self.n1_workloads) + # set up policy + _log.info("Set up policy %s", policy) + self._apply_data(policy, host) + # check connectivity not OK - use retries to allow time to apply new policy + self.assert_no_connectivity(self.n1_workloads, retries=3) + # Restore workload config (i.e. remove the label) + wep_old['metadata']['resourceVersion'] = updated_weps['items'][0]['metadata']['resourceVersion'] + _log.info("Restore workload config %s", wep_old) + self._apply_data(wep_old, host) + updated_weps = yaml.safe_load(host.calicoctl("get workloadEndpoint -o yaml")) + if no_label_expected_result: + # check connectivity OK again - use retries to allow time to apply new policy + self.assert_connectivity(self.n1_workloads, retries=3) + else: + self.assert_no_connectivity(self.n1_workloads) + + +class IpNotFound(Exception): + pass diff --git a/node/windows-packaging/CalicoWindows/kubernetes/kubelet-service.ps1 b/node/windows-packaging/CalicoWindows/kubernetes/kubelet-service.ps1 index 0f0cbf7dce2..508b09de311 100644 --- a/node/windows-packaging/CalicoWindows/kubernetes/kubelet-service.ps1 +++ b/node/windows-packaging/CalicoWindows/kubernetes/kubelet-service.ps1 @@ -58,6 +58,7 @@ $argList = @(` "--hairpin-mode=promiscuous-bridge",` "--cgroups-per-qos=false",` "--enforce-node-allocatable=""""",` + "--rotate-certificates=true",` "--kubeconfig=""c:\k\config"""` ) diff --git a/pod2daemon/csidriver/driver/node.go b/pod2daemon/csidriver/driver/node.go index 0c596e1dd94..6309dc3d8bb 100644 --- a/pod2daemon/csidriver/driver/node.go +++ b/pod2daemon/csidriver/driver/node.go @@ -106,8 +106,8 @@ func (ns *nodeService) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnp // Inspect the file stored at /var/run/nodeagent/creds/volumeID for the pod info podInfo, err := ns.retrievePodInfoFromFile(req.VolumeId) if err != nil { - log.Error("Unable to retrieve pod info") - return nil, status.Error(codes.Internal, "Unable to retrieve pod info") + log.WithError(err).Error("Unable to retrieve pod info") + return nil, status.Errorf(codes.Internal, "Unable to retrieve pod info: %s", err) } // Unmount the relevant directories at the TargetPath diff --git a/pod2daemon/csidriver/main.go b/pod2daemon/csidriver/main.go index daa019858c9..0f3b448e6d1 100644 --- a/pod2daemon/csidriver/main.go +++ b/pod2daemon/csidriver/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Tigera, Inc. All rights reserved. +// Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,10 +27,8 @@ import ( func main() { // Set the log output to stdout to prevent some components from interpreting logs as errors (e.g. fluentd). log.SetOutput(os.Stdout) - // Install a hook that adds file/line no information - log.AddHook(&logutils.ContextHook{}) - // Set up log formatting to reference this component. - log.SetFormatter(&logutils.Formatter{Component: "csi-driver"}) + // Set up logging formatting. + logutils.ConfigureFormatter("csi-driver") // Set the preliminary log level log.SetLevel(log.WarnLevel) diff --git a/process/testing/util/delete-az-rg.sh b/process/testing/util/delete-az-rg.sh new file mode 100755 index 00000000000..833886d91c6 --- /dev/null +++ b/process/testing/util/delete-az-rg.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Copyright (c) 2024 Tigera, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +RESOURCE_GROUP=$1 + +if ! az group show --name "${RESOURCE_GROUP}" --subscription ${AZ_SUBSCRIPTION_ID} 2>&1 | grep ResourceGroupNotFound; then + echo "Deleting azure resource group ${RESOURCE_GROUP}" + az group delete --name "${RESOURCE_GROUP}" --subscription ${AZ_SUBSCRIPTION_ID} --yes +else + echo "No resource group ${RESOURCE_GROUP} found. Doing nothing" +fi diff --git a/process/testing/winfv-cni-plugin/aso/utils.sh b/process/testing/winfv-cni-plugin/aso/utils.sh index 1cf81ae57cb..e496f969399 100755 --- a/process/testing/winfv-cni-plugin/aso/utils.sh +++ b/process/testing/winfv-cni-plugin/aso/utils.sh @@ -19,8 +19,8 @@ function retry_command() { local CMD=$2 echo - for i in `seq 1 $RETRY`; do - echo Trying $CMD, attempt ${i} + for i in $(seq 1 $RETRY); do + echo "Trying '$CMD', attempt ${i}" $CMD && return 0 || sleep 10 done echo "Command '${CMD}' failed after $RETRY attempts" diff --git a/process/testing/winfv-felix/.gitignore b/process/testing/winfv-felix/.gitignore new file mode 100644 index 00000000000..b989bc01eb9 --- /dev/null +++ b/process/testing/winfv-felix/.gitignore @@ -0,0 +1,2 @@ +run-cni-fv.ps1 +run-felix-fv.ps1 diff --git a/process/testing/winfv/README.md b/process/testing/winfv-felix/README.md similarity index 100% rename from process/testing/winfv/README.md rename to process/testing/winfv-felix/README.md diff --git a/process/testing/winfv/calico-node-windows.yaml b/process/testing/winfv-felix/calico-node-windows.yaml similarity index 100% rename from process/testing/winfv/calico-node-windows.yaml rename to process/testing/winfv-felix/calico-node-windows.yaml diff --git a/process/testing/winfv-felix/capz/.gitignore b/process/testing/winfv-felix/capz/.gitignore new file mode 100644 index 00000000000..fb2f0c7890d --- /dev/null +++ b/process/testing/winfv-felix/capz/.gitignore @@ -0,0 +1,13 @@ +bin/* +*.log +.cluster_created +.calico_installed +.sshkey +.sshkey.pub +kubeconfig +scp-from-node.sh +scp-to-node.sh +ssh-node.sh +win-capz.yaml +tigera-operator.yaml +tigera-prometheus-operator.yaml diff --git a/process/testing/winfv/capz/Makefile b/process/testing/winfv-felix/capz/Makefile similarity index 89% rename from process/testing/winfv/capz/Makefile rename to process/testing/winfv-felix/capz/Makefile index c4f8e36197b..a893fc7b729 100644 --- a/process/testing/winfv/capz/Makefile +++ b/process/testing/winfv-felix/capz/Makefile @@ -9,7 +9,7 @@ CLUSTER_CREATED_MARKER:=.cluster_created .PHONY: create-cluster create-cluster: $(CLUSTER_CREATED_MARKER) -$(CLUSTER_CREATED_MARKER): $(BINDIR)/kind $(BINDIR)/kubectl $(BINDIR)/clusterctl +$(CLUSTER_CREATED_MARKER): $(BINDIR)/kind $(BINDIR)/kubectl $(BINDIR)/clusterctl $(BINDIR)/yq @echo "Creating cluster $(CLUSTER_NAME_CAPZ) ..." ./create-cluster.sh $(MAKE) generate-helpers @@ -18,19 +18,16 @@ $(CLUSTER_CREATED_MARKER): $(BINDIR)/kind $(BINDIR)/kubectl $(BINDIR)/clusterctl .PHONY: delete-cluster delete-cluster: $(BINDIR)/kind $(BINDIR)/kubectl -ifeq (,$(wildcard $(CLUSTER_CREATED_MARKER))) - @echo "Cluster marker '$(CLUSTER_CREATED_MARKER)' does not exist, doing nothing" -else @echo "Azure resources for cluster $(CLUSTER_NAME_CAPZ) will now be deleted, this can take up to 20 minutes" -$(BINDIR)/kubectl delete cluster $(CLUSTER_NAME_CAPZ) -$(BINDIR)/kind delete cluster --name kind${SUFFIX} + -az group delete --name $(CI_RG) -y -rm -f kubeconfig -rm -f win-capz.yaml -rm -f tigera-operator.yaml -rm -f tigera-prometheus-operator.yaml -rm -f $(HELPERS) -rm -f $(CLUSTER_CREATED_MARKER) $(CALICO_INSTALLED_MARKER) -endif CALICO_INSTALLED_MARKER:=.calico_installed @@ -70,6 +67,12 @@ $(BINDIR)/clusterctl: touch $@ $(BINDIR)/clusterctl version +$(BINDIR)/yq: + mkdir -p $(@D) + curl -sSf -L --retry 5 https://github.com/mikefarah/yq/releases/download/$(YQ_VERSION)/yq_linux_$(ARCH) -o $(BINDIR)/yq + chmod +x $@ + touch $@ + .PHONY: clean clean: -rm -f kubeconfig @@ -77,8 +80,10 @@ clean: -rm -f tigera-operator.yaml -rm -f .sshkey .sshkey.pub -rm -f $(HELPERS) + -rm -f az-output.log .PHONY: dist-clean dist-clean: clean -rm -rf $(BINDIR) -rm -f $(CLUSTER_CREATED_MARKER) $(CALICO_INSTALLED_MARKER) + -rm -f *.log diff --git a/process/testing/winfv/capz/OSS/custom-resources.yaml b/process/testing/winfv-felix/capz/OSS/custom-resources.yaml similarity index 100% rename from process/testing/winfv/capz/OSS/custom-resources.yaml rename to process/testing/winfv-felix/capz/OSS/custom-resources.yaml diff --git a/process/testing/winfv/capz/README.md b/process/testing/winfv-felix/capz/README.md similarity index 94% rename from process/testing/winfv/capz/README.md rename to process/testing/winfv-felix/capz/README.md index 9c731430ee8..ce83cdc3651 100644 --- a/process/testing/winfv/capz/README.md +++ b/process/testing/winfv-felix/capz/README.md @@ -45,6 +45,8 @@ Optionally, define `PRODUCT`, `RELEASE_STREAM` and/or `HASH_RELEASE`: make install-calico PRODUCT=calient RELEASE_STREAM=master HASH_RELEASE=true ``` +(Use `RELEASE_STREAM=local` to use local manifests from the monorepo instead of pulling them) + To access your cluster, run `kubectl --kubeconfig=./kubeconfig ...` ### Access Linux or Windows nodes diff --git a/process/testing/winfv/capz/create-cluster.sh b/process/testing/winfv-felix/capz/create-cluster.sh old mode 100644 new mode 100755 similarity index 68% rename from process/testing/winfv/capz/create-cluster.sh rename to process/testing/winfv-felix/capz/create-cluster.sh index b192f57f8cb..97798445796 --- a/process/testing/winfv/capz/create-cluster.sh +++ b/process/testing/winfv-felix/capz/create-cluster.sh @@ -41,7 +41,24 @@ set -o pipefail export AZURE_CONTROL_PLANE_MACHINE_TYPE export AZURE_NODE_MACHINE_TYPE -# Number of Linux node is same as number of Windows nodes +export AZURE_CLIENT_ID_USER_ASSIGNED_IDENTITY=$AZURE_CLIENT_ID # for compatibility with CAPZ v1.16 templates + +# Create the resource group and managed identity for the cluster CI +rm az-output.log || true +{ +echo "az group create --name ${CI_RG} --location ${AZURE_LOCATION}" +az group create --name ${CI_RG} --location ${AZURE_LOCATION} +echo +echo "az identity create --name ${USER_IDENTITY} --resource-group ${CI_RG} --location ${AZURE_LOCATION}" +az identity create --name ${USER_IDENTITY} --resource-group ${CI_RG} --location ${AZURE_LOCATION} +sleep 10s +export USER_IDENTITY_ID=$(az identity show --resource-group "${CI_RG}" --name "${USER_IDENTITY}" | jq -r .principalId) +echo +echo az role assignment create --assignee-object-id "${USER_IDENTITY_ID}" --assignee-principal-type "ServicePrincipal" --role "Contributor" --scope "/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${CI_RG}" +az role assignment create --assignee-object-id "${USER_IDENTITY_ID}" --assignee-principal-type "ServicePrincipal" --role "Contributor" --scope "/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${CI_RG}" +} >> az-output.log 2>&1 + +# Number of Linux worker nodes is the same as number of Windows worker nodes : ${WIN_NODE_COUNT:=2} TOTAL_NODES=$((WIN_NODE_COUNT*2+1)) SEMAPHORE="${SEMAPHORE:="false"}" @@ -57,6 +74,7 @@ echo ' WIN_NODE_COUNT='${WIN_NODE_COUNT} : ${KIND:=./bin/kind} : ${KUBECTL:=./bin/kubectl} : ${CLUSTERCTL:=./bin/clusterctl} +: ${YQ:=./bin/yq} : ${KCAPZ:="${KUBECTL} --kubeconfig=./kubeconfig"} # Base64 encode the variables @@ -69,8 +87,6 @@ else export SUFFIX="-${RAND}" fi - - # Settings needed for AzureClusterIdentity used by the AzureCluster export AZURE_CLUSTER_IDENTITY_SECRET_NAME="cluster-identity-secret" export CLUSTER_IDENTITY_NAME="cluster-identity" @@ -118,19 +134,23 @@ ${CLUSTERCTL} generate cluster ${CLUSTER_NAME_CAPZ} \ --flavor machinepool-windows \ > win-capz.yaml -retry_command 900 "${KUBECTL} apply -f win-capz.yaml" +# Cluster templates authenticate with Workload Identity by default. Modify the AzureClusterIdentity for ServicePrincipal authentication. +# See https://capz.sigs.k8s.io/topics/identities for more details. +${YQ} -i "with(. | select(.kind == \"AzureClusterIdentity\"); .spec.type |= \"ServicePrincipal\" | .spec.clientSecret.name |= \"${AZURE_CLUSTER_IDENTITY_SECRET_NAME}\" | .spec.clientSecret.namespace |= \"${AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE}\")" win-capz.yaml + +retry_command 600 "${KUBECTL} apply -f win-capz.yaml" # Wait for CAPZ deployments -${KUBECTL} wait --for=condition=Available --timeout=5m -n capz-system deployment -l cluster.x-k8s.io/provider=infrastructure-azure +timeout --foreground 600 bash -c "while ! ${KUBECTL} wait --for=condition=Available --timeout=30s -n capz-system deployment -l cluster.x-k8s.io/provider=infrastructure-azure; do sleep 5; done" # Wait for the kubeconfig to become available. -timeout --foreground 900 bash -c "while ! ${KUBECTL} get secrets | grep ${CLUSTER_NAME_CAPZ}-kubeconfig; do sleep 5; done" +timeout --foreground 600 bash -c "while ! ${KUBECTL} get secrets | grep ${CLUSTER_NAME_CAPZ}-kubeconfig; do sleep 5; done" # Get kubeconfig and store it locally. ${CLUSTERCTL} get kubeconfig ${CLUSTER_NAME_CAPZ} > ./kubeconfig -timeout --foreground 900 bash -c "while ! ${KUBECTL} --kubeconfig=./kubeconfig get nodes | grep control-plane; do sleep 5; done" -echo "Cluster config is ready at ./kubeconfig. Run \'${KUBECTL} --kubeconfig=./kubeconfig ...\' to work with the new target cluster" +timeout --foreground 600 bash -c "while ! ${KUBECTL} --kubeconfig=./kubeconfig get nodes | grep control-plane; do sleep 5; done" +echo "Cluster config is ready at ./kubeconfig. Run '${KUBECTL} --kubeconfig=./kubeconfig ...' to work with the new target cluster" echo "Waiting for ${TOTAL_NODES} nodes to have been provisioned..." -timeout --foreground 900 bash -c "while ! ${KCAPZ} get nodes | grep ${KUBE_VERSION} | wc -l | grep ${TOTAL_NODES}; do sleep 5; done" +timeout --foreground 600 bash -c "while ! ${KCAPZ} get nodes | grep ${KUBE_VERSION} | wc -l | grep ${TOTAL_NODES}; do sleep 5; done" echo "Seen all ${TOTAL_NODES} nodes" # Do NOT instal Azure cloud provider (clear taint instead) @@ -140,9 +160,9 @@ retry_command 300 "${KCAPZ} taint nodes --selector=!node-role.kubernetes.io/cont echo "Done creating cluster" -ID0=`${KCAPZ} get node -o wide | grep win-p-win000000 | awk '{print $6}' | awk -F '.' '{print $4}'` -echo "ID0: $ID0" -if [[ ${WIN_NODE_COUNT} -gt 1 ]]; then - ID1=`${KCAPZ} get node -o wide | grep win-p-win000001 | awk '{print $6}' | awk -F '.' '{print $4}'` - echo "ID1:$ID1" -fi +WIN_NODES=$(${KCAPZ} get nodes -o wide -l kubernetes.io/os=windows --no-headers | awk '{print $6}' | awk -F '.' '{print $4}' | sort) +i=0 +for n in ${WIN_NODES} +do + echo "ID$i: $n"; i=$(expr $i + 1) +done diff --git a/process/testing/winfv/capz/export-env.sh b/process/testing/winfv-felix/capz/export-env.sh old mode 100644 new mode 100755 similarity index 60% rename from process/testing/winfv/capz/export-env.sh rename to process/testing/winfv-felix/capz/export-env.sh index 91bdadcb805..5cde0b1ba60 --- a/process/testing/winfv/capz/export-env.sh +++ b/process/testing/winfv-felix/capz/export-env.sh @@ -1,8 +1,11 @@ export CLUSTER_NAME_CAPZ="${CLUSTER_NAME_CAPZ:=${USER}-capz-win}" -export AZURE_LOCATION="${AZURE_LOCATION:="westcentralus"}" +export AZURE_LOCATION="${AZURE_LOCATION:="westus2"}" # [Optional] Select resource group. The default value is ${CLUSTER_NAME_CAPZ}-rg. export AZURE_RESOURCE_GROUP="${AZURE_RESOURCE_GROUP:=${CLUSTER_NAME_CAPZ}-rg}" +# These are required by the machinepool-windows template +export CI_RG="${AZURE_RESOURCE_GROUP}-ci" +export USER_IDENTITY="cloud-provider-user-identity" # Optional, can be windows-2019 or windows-2022 (default) # https://capz.sigs.k8s.io/developers/development.html @@ -13,16 +16,10 @@ export WINDOWS_SERVER_VERSION="${WINDOWS_SERVER_VERSION:="windows-2022"}" export AZURE_CONTROL_PLANE_MACHINE_TYPE="${AZURE_CONTROL_PLANE_MACHINE_TYPE:="Standard_D2s_v3"}" export AZURE_NODE_MACHINE_TYPE="${AZURE_NODE_MACHINE_TYPE:="Standard_D2s_v3"}" -# Get KINDEST_NODE_VERSION variable from metadata.mk, default to a value if it cannot be found -SCRIPT_CURRENT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -METADATAMK=${SCRIPT_CURRENT_DIR}/../../../metadata.mk -if [ -f ${METADATAMK} ]; then - export KUBE_VERSION=$(grep KINDEST_NODE_VERSION= ${METADATAMK} | cut -d "=" -f 2) -else - export KUBE_VERSION=v1.27.11 -fi -export CLUSTER_API_VERSION="${CLUSTER_API_VERSION:="v1.6.3"}" +export KUBE_VERSION=v1.28.9 +export KIND_VERSION=v0.24.0 +export CLUSTER_API_VERSION="${CLUSTER_API_VERSION:="v1.8.1"}" export AZURE_PROVIDER_VERSION="${AZURE_PROVIDER_VERSION:="v1.13.2"}" -export KIND_VERSION="${KIND_VERSION:="v0.22.0"}" -export CONTAINERD_VERSION="${CONTAINERD_VERSION:="v1.7.13"}" +export CONTAINERD_VERSION="${CONTAINERD_VERSION:="v1.7.20"}" export CALICO_VERSION="${CALICO_VERSION:="v3.28.1"}" +export YQ_VERSION="${YQ_VERSION:="v4.44.3"}" diff --git a/process/testing/winfv-felix/capz/generate-helpers.sh b/process/testing/winfv-felix/capz/generate-helpers.sh new file mode 100755 index 00000000000..2bbb7067752 --- /dev/null +++ b/process/testing/winfv-felix/capz/generate-helpers.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# Copyright (c) 2024 Tigera, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +set -e +LOCAL_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +# scp from OpenSSH versions 8.8 and newer requires a '-O' flag in order to work correctly +# with windows ssh servers, but older versions don't know about that flag. Only use +# it when necessary (i.e. supported). +OFLAG="-O " +if [ "$(scp -O 2>&1 | grep -c 'unknown option -- O')" -gt 0 ]; then + OFLAG="" +fi + +: ${KUBECTL:=${LOCAL_PATH}/bin/kubectl} +: ${WIN_NODE_COUNT:=2} + +KCAPZ="${KUBECTL} --kubeconfig=./kubeconfig" + +APISERVER=$(${KCAPZ} config view -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME_CAPZ}\")].cluster.server}" | awk -F/ '{print $3}' | awk -F: '{print $1}') +if [ -z "${APISERVER}" ] ; then + echo "Failed to get apiserver public ip" + exit 1 +fi +echo +echo APISERVER: ${APISERVER} + +${KCAPZ} get node -o wide + +echo +echo "Generating helper files" +CONNECT_FILE="ssh-node.sh" +echo "#---------Connect to Instance--------" | tee ${CONNECT_FILE} +echo "#usage: ./ssh-node.sh 6 to ssh into 10.1.0.6" | tee -a ${CONNECT_FILE} +echo "#usage: ./ssh-node.sh 6 'Get-Service -Name kubelet' > output" | tee -a ${CONNECT_FILE} +echo ssh -t -i ${LOCAL_PATH}/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o \'ProxyCommand ssh -i ${LOCAL_PATH}/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -W %h:%p capi@${APISERVER}\' capi@10.1.0.\$1 \$2 | tee -a ${CONNECT_FILE} +chmod +x ${CONNECT_FILE} +echo + +SCP_FILE="scp-to-node.sh" +echo "#---------Copy files to Instance--------" | tee ${SCP_FILE} +echo "#usage: ./scp-to-node.sh 6 kubeconfig c:\\\\k\\\\kubeconfig -- copy kubeconfig to 10.1.0.6" | tee -a ${SCP_FILE} +echo "#usage: ./scp-to-node.sh 6 images/ebpf-for-windows-c-temp.zip 'c:\\' -- copy temp zip to 10.1.0.6" | tee -a ${SCP_FILE} +echo scp ${OFLAG} -i ${LOCAL_PATH}/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o \'ProxyCommand ssh -i ${LOCAL_PATH}/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -W %h:%p capi@${APISERVER}\' \$2 capi@10.1.0.\$1:\$3 | tee -a ${SCP_FILE} +chmod +x ${SCP_FILE} +echo + +SCP_FROM_NODE="scp-from-node.sh" +echo "#---------Copy files from Instance--------" | tee ${SCP_FROM_NODE} +echo "#usage: ./scp-from-node.sh 6 c:/k/calico.log ./calico.log" | tee -a ${SCP_FROM_NODE} +echo scp ${OFLAG} -r -i ${LOCAL_PATH}/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o \'ProxyCommand ssh -i ${LOCAL_PATH}/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -W %h:%p capi@${APISERVER}\' capi@10.1.0.\$1:\$2 \$3 | tee -a ${SCP_FROM_NODE} +chmod +x ${SCP_FROM_NODE} + +# Update env file with Windows ips +sed -i "/^export ID[0-9]=\"[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\"/d" ./export-env.sh + +IP0=`$KCAPZ get node win-p-win000000 -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}'` +echo; echo "Windows nodes IPs" +echo "IP0: $IP0" + +if [[ $WIN_NODE_COUNT -gt 1 ]]; then + IP1=`$KCAPZ get node win-p-win000001 -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}'` + echo "IP1: $IP1" +fi diff --git a/process/testing/winfv/capz/install-calico.sh b/process/testing/winfv-felix/capz/install-calico.sh old mode 100644 new mode 100755 similarity index 81% rename from process/testing/winfv/capz/install-calico.sh rename to process/testing/winfv-felix/capz/install-calico.sh index d234c195664..0bb5e260259 --- a/process/testing/winfv/capz/install-calico.sh +++ b/process/testing/winfv-felix/capz/install-calico.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2022 Tigera, Inc. All rights reserved. +# Copyright (c) 2022-2024 Tigera, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -39,6 +39,9 @@ if [ ${PRODUCT} == 'calient' ]; then : "${TSEE_TEST_LICENSE:?Environment variable empty or not defined.}" fi +SCRIPT_CURRENT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 && pwd -P )" +LOCAL_MANIFESTS_DIR="${SCRIPT_CURRENT_DIR}/../../../../manifests" + if [ ${PRODUCT} == 'calient' ]; then RELEASE_BASE_URL="https://downloads.tigera.io/ee/${RELEASE_STREAM}" else @@ -58,21 +61,38 @@ if [ ${HASH_RELEASE} == 'true' ]; then RELEASE_BASE_URL=$(curl -sS ${URL_HASH}) fi -# Check release url and installation scripts -echo "Set release base url ${RELEASE_BASE_URL}" -sed -i "s,export RELEASE_BASE_URL.*,export RELEASE_BASE_URL=\"${RELEASE_BASE_URL}\"," ./export-env.sh +if [[ ${RELEASE_STREAM} != 'local' ]]; then + # Check release url and installation scripts + echo "Set release base url ${RELEASE_BASE_URL}" + sed -i "s,export RELEASE_BASE_URL.*,export RELEASE_BASE_URL=\"${RELEASE_BASE_URL}\"," ./export-env.sh +fi + # Create a storage class and persistent volume for Calico Enterprise. if [ ${PRODUCT} == 'calient' ]; then ${KCAPZ} create -f ./EE/storage-class-azure-file.yaml ${KCAPZ} create -f ./EE/persistent-volume.yaml fi + # Install Calico on Linux nodes -curl -sSf -L --retry 5 ${RELEASE_BASE_URL}/manifests/tigera-operator.yaml -o tigera-operator.yaml -${KCAPZ} create -f ./tigera-operator.yaml +if [[ ${RELEASE_STREAM} == 'local' ]]; then + # Use local manifests + ${KCAPZ} create -f ${LOCAL_MANIFESTS_DIR}/tigera-operator.yaml +else + # Use release url + echo "Set release base url ${RELEASE_BASE_URL}" + sed -i "s,export RELEASE_BASE_URL.*,export RELEASE_BASE_URL=\"${RELEASE_BASE_URL}\"," ./export-env.sh + curl -sSf -L --retry 5 ${RELEASE_BASE_URL}/manifests/tigera-operator.yaml -o tigera-operator.yaml + ${KCAPZ} create -f ./tigera-operator.yaml +fi + if [[ ${PRODUCT} == 'calient' ]]; then # Install prometheus operator - curl -sSf -L --retry 5 ${RELEASE_BASE_URL}/manifests/tigera-prometheus-operator.yaml -o tigera-prometheus-operator.yaml - ${KCAPZ} create -f ./tigera-prometheus-operator.yaml + if [[ ${RELEASE_STREAM} == 'local' ]]; then + ${KCAPZ} create -f ${LOCAL_MANIFESTS_DIR}/tigera-prometheus-operator.yaml + else + curl -sSf -L --retry 5 ${RELEASE_BASE_URL}/manifests/tigera-prometheus-operator.yaml -o tigera-prometheus-operator.yaml + ${KCAPZ} create -f ./tigera-prometheus-operator.yaml + fi # Install pull secret. ${KCAPZ} create secret generic tigera-pull-secret \ @@ -84,12 +104,6 @@ if [[ ${PRODUCT} == 'calient' ]]; then ${KCAPZ} patch deployment tigera-operator -n tigera-operator --patch '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"tigera-pull-secret"}]}}}}' fi - # Install prometheus operator pull secret. - ${KCAPZ} create secret generic tigera-pull-secret \ - --type=kubernetes.io/dockerconfigjson -n tigera-prometheus \ - --from-file=.dockerconfigjson=${GCR_IO_PULL_SECRET} - ${KCAPZ} patch deployment calico-prometheus-operator -n tigera-prometheus --patch '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"tigera-pull-secret"}]}}}}' - # Create custom resources ${KCAPZ} create -f ./EE/custom-resources.yaml @@ -137,7 +151,7 @@ echo "Calico is ready on Windows nodes" # Create the kube-proxy-windows daemonset for iter in {1..5};do - curl -sSf -L https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/calico/kube-proxy/kube-proxy.yml | sed "s/KUBE_PROXY_VERSION/${KUBE_VERSION}/g" | ${KCAPZ} apply -f - && exit_code=0 && break || echo "download error: retry $iter in 5s" && sleep 5; + curl -sSf -L https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/calico/kube-proxy/kube-proxy.yml | sed "s/KUBE_PROXY_VERSION/${KUBE_VERSION}/g" | ${KCAPZ} apply -f - && break || echo "download error: retry $iter in 5s" && sleep 5; done; echo "Wait for kube-proxy to be ready on Windows nodes..." diff --git a/process/testing/winfv/capz/replace-win-containerd.ps1 b/process/testing/winfv-felix/capz/replace-win-containerd.ps1 similarity index 100% rename from process/testing/winfv/capz/replace-win-containerd.ps1 rename to process/testing/winfv-felix/capz/replace-win-containerd.ps1 diff --git a/process/testing/winfv/capz/replace-win-containerd.sh b/process/testing/winfv-felix/capz/replace-win-containerd.sh similarity index 100% rename from process/testing/winfv/capz/replace-win-containerd.sh rename to process/testing/winfv-felix/capz/replace-win-containerd.sh diff --git a/process/testing/winfv/capz/utils.sh b/process/testing/winfv-felix/capz/utils.sh old mode 100644 new mode 100755 similarity index 92% rename from process/testing/winfv/capz/utils.sh rename to process/testing/winfv-felix/capz/utils.sh index fc4fb477305..e0908f6e63f --- a/process/testing/winfv/capz/utils.sh +++ b/process/testing/winfv-felix/capz/utils.sh @@ -20,8 +20,8 @@ function retry_command() { local CMD=$2 echo - for i in `seq 1 $RETRY`; do - echo Trying $CMD, attempt ${i} + for i in $(seq 1 $RETRY); do + echo "Trying '$CMD', attempt ${i}" $CMD && return 0 || sleep 10 done echo "Command '${CMD}' failed after $RETRY attempts" diff --git a/process/testing/winfv/cloudformation-simple-vpc.json b/process/testing/winfv-felix/cloudformation-simple-vpc.json similarity index 100% rename from process/testing/winfv/cloudformation-simple-vpc.json rename to process/testing/winfv-felix/cloudformation-simple-vpc.json diff --git a/process/testing/winfv/cloudformation-windows-server.json b/process/testing/winfv-felix/cloudformation-windows-server.json similarity index 100% rename from process/testing/winfv/cloudformation-windows-server.json rename to process/testing/winfv-felix/cloudformation-windows-server.json diff --git a/process/testing/winfv/create_kubeadm_cluster.sh b/process/testing/winfv-felix/create_kubeadm_cluster.sh similarity index 100% rename from process/testing/winfv/create_kubeadm_cluster.sh rename to process/testing/winfv-felix/create_kubeadm_cluster.sh diff --git a/process/testing/winfv/infra/client.yaml b/process/testing/winfv-felix/infra/client.yaml similarity index 100% rename from process/testing/winfv/infra/client.yaml rename to process/testing/winfv-felix/infra/client.yaml diff --git a/process/testing/winfv/infra/ee/role.yaml b/process/testing/winfv-felix/infra/ee/role.yaml similarity index 100% rename from process/testing/winfv/infra/ee/role.yaml rename to process/testing/winfv-felix/infra/ee/role.yaml diff --git a/process/testing/winfv/infra/egress.yaml b/process/testing/winfv-felix/infra/egress.yaml similarity index 100% rename from process/testing/winfv/infra/egress.yaml rename to process/testing/winfv-felix/infra/egress.yaml diff --git a/process/testing/winfv/infra/ingress.yaml b/process/testing/winfv-felix/infra/ingress.yaml similarity index 100% rename from process/testing/winfv/infra/ingress.yaml rename to process/testing/winfv-felix/infra/ingress.yaml diff --git a/process/testing/winfv/infra/installation-bgp.yaml b/process/testing/winfv-felix/infra/installation-bgp.yaml similarity index 100% rename from process/testing/winfv/infra/installation-bgp.yaml rename to process/testing/winfv-felix/infra/installation-bgp.yaml diff --git a/process/testing/winfv/infra/installation-vxlan.yaml b/process/testing/winfv-felix/infra/installation-vxlan.yaml similarity index 100% rename from process/testing/winfv/infra/installation-vxlan.yaml rename to process/testing/winfv-felix/infra/installation-vxlan.yaml diff --git a/process/testing/winfv/infra/nginx.yaml b/process/testing/winfv-felix/infra/nginx.yaml similarity index 100% rename from process/testing/winfv/infra/nginx.yaml rename to process/testing/winfv-felix/infra/nginx.yaml diff --git a/process/testing/winfv/infra/porter.yaml b/process/testing/winfv-felix/infra/porter.yaml similarity index 100% rename from process/testing/winfv/infra/porter.yaml rename to process/testing/winfv-felix/infra/porter.yaml diff --git a/process/testing/winfv/infra/setup.sh b/process/testing/winfv-felix/infra/setup.sh similarity index 100% rename from process/testing/winfv/infra/setup.sh rename to process/testing/winfv-felix/infra/setup.sh diff --git a/process/testing/winfv/restart-felix.ps1 b/process/testing/winfv-felix/restart-felix.ps1 similarity index 100% rename from process/testing/winfv/restart-felix.ps1 rename to process/testing/winfv-felix/restart-felix.ps1 diff --git a/process/testing/winfv/run-fv-cni-plugin.ps1 b/process/testing/winfv-felix/run-fv-cni-plugin.ps1 similarity index 100% rename from process/testing/winfv/run-fv-cni-plugin.ps1 rename to process/testing/winfv-felix/run-fv-cni-plugin.ps1 diff --git a/process/testing/winfv/run-fv-full.ps1 b/process/testing/winfv-felix/run-fv-full.ps1 similarity index 96% rename from process/testing/winfv/run-fv-full.ps1 rename to process/testing/winfv-felix/run-fv-full.ps1 index 84d2236213a..8cec7985721 100644 --- a/process/testing/winfv/run-fv-full.ps1 +++ b/process/testing/winfv-felix/run-fv-full.ps1 @@ -10,6 +10,10 @@ Param( $Root="c:\\CalicoWindows" +if ($Provisioner -eq "capz") { + Set-Item -Path env:HPC -Value "true" +} + # Force powershell to run in 64-bit mode . if ([Environment]::Is64BitProcess -eq $false) { write-warning "This script requires PowerShell 64-bit, relaunching..." @@ -22,7 +26,7 @@ if ([Environment]::Is64BitProcess -eq $false) { } if ($Provisioner -ne "capz") { - # Install Calico for Windows + # Install Calico for Windows using the manual installation method Invoke-WebRequest https://docs.projectcalico.org/scripts/install-calico-windows.ps1 -OutFile c:\\install-calico-windows.ps1 c:\\install-calico-windows.ps1 -KubeVersion $KubeVersion diff --git a/process/testing/winfv/setup-fv-capz.sh b/process/testing/winfv-felix/setup-fv-capz.sh similarity index 63% rename from process/testing/winfv/setup-fv-capz.sh rename to process/testing/winfv-felix/setup-fv-capz.sh index 0defc78afc6..50001025b24 100644 --- a/process/testing/winfv/setup-fv-capz.sh +++ b/process/testing/winfv-felix/setup-fv-capz.sh @@ -27,16 +27,28 @@ set -o nounset set -o pipefail GIT_VERSION=$(git describe --tags --dirty --long --always --abbrev=12) -CALICO_HOME=$(cd $(dirname $0)/../../../; pwd) -CAPZ_LOCATION=$CALICO_HOME/process/testing/winfv/capz -KUBECONFIG=$CALICO_HOME/process/testing/winfv/capz/kubeconfig +CALICO_HOME=$(cd "$(dirname $0)"/../../../; pwd) +CAPZ_LOCATION=$CALICO_HOME/process/testing/winfv-felix/capz +KUBECONFIG=$CALICO_HOME/process/testing/winfv-felix/capz/kubeconfig +KUBECTL=$CAPZ_LOCATION/bin/kubectl +KCAPZ="${KUBECTL} --kubeconfig=${KUBECONFIG}" +REPORT_DIR=$CALICO_HOME/process/testing/winfv-felix/report +SSH_OUTPUT_FILE=$REPORT_DIR/ssh_output.log SEMAPHORE="${SEMAPHORE:="false"}" export RAND=$(tr -dc a-z0-9 output - $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'ctr --namespace k8s.io images import --base-name calico/cni-windows c:\calico-cni-plugin-windows.tar --all-platforms' > output + $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'ctr --namespace k8s.io images import --base-name calico/node-windows c:\calico-node-windows.tar --all-platforms' >> $SSH_OUTPUT_FILE + $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'ctr --namespace k8s.io images import --base-name calico/cni-windows c:\calico-cni-plugin-windows.tar --all-platforms' >> $SSH_OUTPUT_FILE } function upload_fv(){ if [[ $FV_TYPE == "cni-plugin" ]]; then - $CAPZ_LOCATION/scp-to-node.sh $WIN_NODE_IP $CALICO_HOME/process/testing/winfv/run-cni-fv.ps1 c:\\run-cni-fv.ps1 + $CAPZ_LOCATION/scp-to-node.sh $WIN_NODE_IP $CALICO_HOME/process/testing/winfv-cni-plugin/run-cni-fv.ps1 c:\\run-cni-fv.ps1 $CAPZ_LOCATION/scp-to-node.sh $WIN_NODE_IP $CALICO_HOME/cni-plugin/bin/windows/win-fv.exe c:\\k\\win-cni-fv.exe elif [[ $FV_TYPE == "calico-felix" ]]; then - $CAPZ_LOCATION/scp-to-node.sh $WIN_NODE_IP $CALICO_HOME/process/testing/winfv/run-felix-fv.ps1 c:\\run-felix-fv.ps1 + $CAPZ_LOCATION/scp-to-node.sh $WIN_NODE_IP $CALICO_HOME/process/testing/winfv-felix/run-felix-fv.ps1 c:\\run-felix-fv.ps1 $CAPZ_LOCATION/scp-to-node.sh $WIN_NODE_IP $CALICO_HOME/felix/fv/win-fv.exe c:\\k\\win-felix-fv.exe fi } @@ -115,8 +131,8 @@ function prepare_windows_images(){ function prepare_fv(){ if [[ $FV_TYPE == "cni-plugin" ]]; then make -C $CALICO_HOME/cni-plugin bin/windows/win-fv.exe - FV_RUN_CNI=$CALICO_HOME/process/testing/winfv/run-cni-fv.ps1 - cp $CALICO_HOME/process/testing/winfv/run-fv-cni-plugin.ps1 $FV_RUN_CNI + FV_RUN_CNI=$CALICO_HOME/process/testing/winfv-cni-plugin/run-cni-fv.ps1 + cp $CALICO_HOME/process/testing/winfv-cni-plugin/run-fv-cni-plugin.ps1 $FV_RUN_CNI sed -i "s??${KUBE_VERSION}?g" $FV_RUN_CNI sed -i "s??${LINUX_NODE}?g" $FV_RUN_CNI sed -i "s??${WINDOWS_SERVER_VERSION}?g" $FV_RUN_CNI @@ -125,8 +141,8 @@ function prepare_fv(){ sed -i "s?win-fv.exe?win-cni-fv.exe?g" $FV_RUN_CNI elif [[ $FV_TYPE == "calico-felix" ]]; then make -C $CALICO_HOME/felix fv/win-fv.exe - FV_RUN_FELIX=$CALICO_HOME/process/testing/winfv/run-felix-fv.ps1 - cp $CALICO_HOME/process/testing/winfv/run-fv-full.ps1 $FV_RUN_FELIX + FV_RUN_FELIX=$CALICO_HOME/process/testing/winfv-felix/run-felix-fv.ps1 + cp $CALICO_HOME/process/testing/winfv-felix/run-fv-full.ps1 $FV_RUN_FELIX sed -i "s??${KUBE_VERSION}?g" $FV_RUN_FELIX sed -i "s??${LINUX_NODE}?g" $FV_RUN_FELIX sed -i "s??${WINDOWS_SERVER_VERSION}?g" $FV_RUN_FELIX @@ -143,8 +159,8 @@ function prepare_fv(){ function wait_for_nodes(){ #Wait for calico-node-windows daemon set to update sleep 30 - for i in `seq 1 30`; do - if [[ `kubectl get ds calico-node-windows -n calico-system --no-headers --kubeconfig $KUBECONFIG | awk -v OFS='\t\t' '{print $6}'` = "$WIN_NODE_COUNT" ]] ; then + for i in $(seq 1 30); do + if [[ $(${KCAPZ} get ds calico-node-windows -n calico-system --no-headers | awk -v OFS='\t\t' '{print $6}') = "$WIN_NODE_COUNT" ]] ; then echo "Calico Node Windows is ready" return fi @@ -157,19 +173,19 @@ function wait_for_nodes(){ function update_windows_node(){ upload_calico_images - kubectl annotate ds -n calico-system calico-node-windows unsupported.operator.tigera.io/ignore="true" --kubeconfig $KUBECONFIG - kubectl patch ds -n calico-system calico-node-windows --patch-file $CALICO_HOME/process/testing/winfv/calico-node-windows.yaml --kubeconfig $KUBECONFIG + ${KCAPZ} annotate ds -n calico-system calico-node-windows unsupported.operator.tigera.io/ignore="true" + ${KCAPZ} patch ds -n calico-system calico-node-windows --patch-file $CALICO_HOME/process/testing/winfv-felix/calico-node-windows.yaml } function start_test_infra(){ - $CALICO_HOME/process/testing/winfv/infra/setup.sh $KUBECONFIG + $CALICO_HOME/process/testing/winfv-felix/infra/setup.sh $KUBECONFIG #Wait for porter pod to be running on windows node - for i in `seq 1 30`; do - if [[ `kubectl -n demo get pods porter --no-headers -o custom-columns=NAMESPACE:metadata.namespace,POD:metadata.name,PodIP:status.podIP,READY-true:status.containerStatuses[*].ready --kubeconfig $KUBECONFIG | awk -v OFS='\t\t' '{print $4}'` = "true" ]] ; then - echo "Porter is ready" - return - fi + for i in $(seq 1 30); do + if [[ $(${KCAPZ} -n demo get pods porter --no-headers -o custom-columns=NAMESPACE:metadata.namespace,POD:metadata.name,PodIP:status.podIP,READY-true:status.containerStatuses[*].ready | awk -v OFS='\t\t' '{print $4}') = "true" ]] ; then + echo "Porter is ready" + return + fi echo "Waiting for porter to be ready" sleep 30 done @@ -179,23 +195,19 @@ function start_test_infra(){ function run_windows_fv(){ if [[ $FV_TYPE == "cni-plugin" ]]; then - $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'c:\\run-cni-fv.ps1' > output + $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'c:\\run-cni-fv.ps1' >> $SSH_OUTPUT_FILE elif [[ $FV_TYPE == "calico-felix" ]]; then - $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'c:\\run-felix-fv.ps1' > output + $CAPZ_LOCATION/ssh-node.sh $WIN_NODE_IP 'c:\\run-felix-fv.ps1' >> $SSH_OUTPUT_FILE fi } function get_test_results(){ - $CAPZ_LOCATION/scp-from-node.sh $WIN_NODE_IP c:\\k\\report $CALICO_HOME/process/testing/winfv/ + $CAPZ_LOCATION/scp-from-node.sh $WIN_NODE_IP c:\\k\\report\\* $REPORT_DIR if [[ $SEMAPHORE == "false" ]]; then - cat $CALICO_HOME/process/testing/winfv/report/fv-test.log + cat $REPORT_DIR/fv-test.log fi } -function shutdown_cluster(){ - make -C $CAPZ_LOCATION delete-cluster -} - prepare_env start_cluster prepare_windows_images diff --git a/process/testing/winfv/setup-fv.sh b/process/testing/winfv-felix/setup-fv.sh similarity index 99% rename from process/testing/winfv/setup-fv.sh rename to process/testing/winfv-felix/setup-fv.sh index 1f57cb0ace7..98a643f647d 100755 --- a/process/testing/winfv/setup-fv.sh +++ b/process/testing/winfv-felix/setup-fv.sh @@ -57,7 +57,7 @@ CONTAINER_RUNTIME="${CONTAINER_RUNTIME:=docker}" CONTAINERD_VERSION="${CONTAINERD_VERSION:=1.6.22}" #specify description of AMI,this would be a filter to search AMI. -#we can create a Json file for description and use it. TODO???? +#we can create a Json file for description and use it. TODO??? AMI_1809_DESCRIPTION="Microsoft Windows Server 2019 with Containers Locale English AMI provided by Amazon" AMI_1903_DESCRIPTION="Tigera-Windows Server 1903 image" @@ -313,7 +313,7 @@ function show_all_instances() { echo "Linux node: ubuntu@${LINUX_EIP}" echo "Windows node: ${WINDOWS_EIP}" - echo "For credentials and other info, attach into the running job and go to ~/calico/process/testing/winfv and `cat connect`" + echo "For credentials and other info, attach into the running job and go to ~/calico/process/testing/winfv-felix and `cat connect`" CONNECT_FILE="connect" echo diff --git a/process/testing/winfv/capz/generate-helpers.sh b/process/testing/winfv/capz/generate-helpers.sh deleted file mode 100644 index 95c4671ed4b..00000000000 --- a/process/testing/winfv/capz/generate-helpers.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -set -e -LOCAL_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" - -: ${KUBECTL:=$LOCAL_PATH/bin/kubectl} - -KCAPZ="${KUBECTL} --kubeconfig=./kubeconfig" - -APISERVER=$(${KCAPZ} config view -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME_CAPZ}\")].cluster.server}" | awk -F/ '{print $3}' | awk -F: '{print $1}') -if [ -z "${APISERVER}" ] ; then - echo "Failed to get apiserver public ip" - exit 1 -fi -echo -echo APISERVER: ${APISERVER} - -${KCAPZ} get node -o wide - -echo -echo "Generating helper files" -CONNECT_FILE="ssh-node.sh" -echo "#---------Connect to Instance--------" | tee ${CONNECT_FILE} -echo "#usage: ./ssh-node.sh 6 to ssh into 10.1.0.6" | tee -a ${CONNECT_FILE} -echo "#usage: ./ssh-node.sh 6 'Get-Service -Name kubelet' > output" | tee -a ${CONNECT_FILE} -echo ssh -t -i $LOCAL_PATH/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o \'ProxyCommand ssh -i $LOCAL_PATH/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -W %h:%p capi@${APISERVER}\' capi@10.1.0.\$1 \$2 | tee -a ${CONNECT_FILE} -chmod +x ${CONNECT_FILE} -echo - -SCP_FILE="scp-to-node.sh" -echo "#---------Copy files to Instance--------" | tee ${SCP_FILE} -echo "#usage: ./scp-to-node.sh 6 kubeconfig c:\\\\k\\\\kubeconfig -- copy kubeconfig to 10.1.0.6" | tee -a ${SCP_FILE} -echo "#usage: ./scp-to-node.sh 6 images/ebpf-for-windows-c-temp.zip 'c:\\' -- copy temp zip to 10.1.0.6" | tee -a ${SCP_FILE} -echo scp -i $LOCAL_PATH/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o \'ProxyCommand ssh -i $LOCAL_PATH/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -W %h:%p capi@${APISERVER}\' \$2 capi@10.1.0.\$1:\$3 | tee -a ${SCP_FILE} -chmod +x ${SCP_FILE} -echo - -SCP_FROM_NODE="scp-from-node.sh" -echo "#---------Copy files to Instance--------" | tee ${SCP_FROM_NODE} -echo "#usage: ./scp-from-node.sh 6 c:/k/calico.log ./calico.log" | tee -a ${SCP_FROM_NODE} -echo scp -r -i $LOCAL_PATH/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o \'ProxyCommand ssh -i $LOCAL_PATH/.sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -W %h:%p capi@${APISERVER}\' capi@10.1.0.\$1:\$2 \$3 | tee -a ${SCP_FROM_NODE} -chmod +x ${SCP_FROM_NODE} - -# Update env file with Windows ips -sed -i "/^export ID[0-9]=\"[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\"/d" ./export-env.sh - -IP0=`$KCAPZ get node win-p-win000000 -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}'` -echo; echo "Windows nodes IPs" -echo "IP0: $IP0" - -if [[ $WIN_NODE_COUNT -gt 1 ]]; then - IP1=`$KCAPZ get node win-p-win000001 -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}'` - echo "IP1: $IP1" -fi diff --git a/release/.gitignore b/release/.gitignore new file mode 100644 index 00000000000..80bd8683071 --- /dev/null +++ b/release/.gitignore @@ -0,0 +1,4 @@ +coverage.txt +output/ +tmp/ +*.log diff --git a/release/Makefile b/release/Makefile new file mode 100644 index 00000000000..3ce1246549c --- /dev/null +++ b/release/Makefile @@ -0,0 +1,31 @@ +include ../metadata.mk + +PACKAGE_NAME = github.com/projectcalico/calico/release + +include ../lib.Makefile + +.PHONY: build +build: bin/release + +clean: + @rm -rf ./bin + @rm -rf ./output ./tmp + +bin/release: $(shell find . -name "*.go") + @mkdir -p bin && \ + $(call build_binary, ./build, bin/release) + +############################################################################### +# CI/CD +############################################################################### +.PHONY: ci +ci: static-checks + +############################################################################### +# Release +############################################################################### +.PHONY: release-notes +release-notes: bin/release var-require-all-GITHUB_TOKEN + @ORGANIZATION=$(ORGANIZATION) \ + REPO_ROOT=$(REPO_ROOT) \ + bin/release release generate-release-notes diff --git a/release/README.md b/release/README.md new file mode 100644 index 00000000000..d952cc01c9b --- /dev/null +++ b/release/README.md @@ -0,0 +1,39 @@ +# Release + +This is a tool using for building Calico components for internal and external releases. + +## Getting started + +```sh +make clean +make build +``` + +## Usage + +```sh +./bin/release --help +``` + +## Developer Guide + +### Building and publishing a test release + +This section describes how to build a test release using the locally checked out code, and publish that release to your own GitHub repository and container registry. + +### Building a local release + +Build the release, providing your own registry to use for the images. For example: + +``` +ARCHES=amd64 ./bin/release hashrelease build --skip-validation --build-images --dev-registry +``` + +This may take some time, but will produce a full set of release images as well as an operator image based on the locally checked out commit. Artifacts can be found +in `_output/hashrelease`. + +### Publishing the release + +This section outlines how to publish a test release to your own image registry. + +TODO diff --git a/hack/release/RELEASING.md b/release/RELEASING.md similarity index 96% rename from hack/release/RELEASING.md rename to release/RELEASING.md index 2c8ba6c29a2..f4a1d9db078 100644 --- a/hack/release/RELEASING.md +++ b/release/RELEASING.md @@ -209,7 +209,7 @@ Follow [the tigera/operator release instructions](https://github.com/tigera/oper 1. Build OpenStack packages from the checked out commit. ``` - make -C hack/release/packaging release-publish VERSION=vX.Y.Z + make -C release/packaging release-publish VERSION=vX.Y.Z ``` ### 4.e Update the docs with the new version @@ -229,10 +229,10 @@ Follow [the tigera/operator release instructions](https://github.com/tigera/oper ### Post-release verification 1. Run the post-release checks. The release validation checks will run - they check for the presence of all the required binaries tarballs, tags, etc. - + ``` make VERSION=... FLANNEL_VERSION=... OPERATOR_VERSION=... postrelease-checks - ``` + ``` 1. Check the output of the tests - if any test failed, dig in and understand why. @@ -264,9 +264,6 @@ Release notes for a Calico release contain notable changes across Calico reposit A file called `release-notes/-release-notes.md` will be created with the raw release note content. - > **NOTE**: If you receive a ratelimit error, you can specify a `GITHUB_TOKEN` in the above command to - > increase the number of allowed API calls. [See here for details](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/). - 1. Edit the generated file. The release notes should be edited to highlight a few major enhancements and their value to the user. Bug fixes and other changes should be summarized in a @@ -293,4 +290,4 @@ The `projectcalico/api` repository needs to be updated to stay in sync with the 3. The script will clone the upstream repository (i.e. `projectcalico/calico`), import the updated files, commit them, and create a PR for them 7. Once this is done, it will output a URL for a PR, which you can then review and get approved. -Note that if an auto-api PR already exists for this minor version, it will print an error about the PR existing already; this is fine, and the script will have updated the PR instead. Go to Github, find the PR manually, and review it to ensure everything looks correct, then have it merged. \ No newline at end of file +Note that if an auto-api PR already exists for this minor version, it will print an error about the PR existing already; this is fine, and the script will have updated the PR instead. Go to Github, find the PR manually, and review it to ensure everything looks correct, then have it merged. diff --git a/release/build/main.go b/release/build/main.go new file mode 100644 index 00000000000..63c2b98a55c --- /dev/null +++ b/release/build/main.go @@ -0,0 +1,348 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "io" + "os" + "path/filepath" + + "gopkg.in/natefinch/lumberjack.v2" + + "github.com/projectcalico/calico/release/internal/config" + "github.com/projectcalico/calico/release/internal/registry" + "github.com/projectcalico/calico/release/internal/utils" + "github.com/projectcalico/calico/release/internal/version" + "github.com/projectcalico/calico/release/pkg/builder" + "github.com/projectcalico/calico/release/pkg/tasks" + + "github.com/sirupsen/logrus" + cli "github.com/urfave/cli/v2" +) + +const ( + skipValidationFlag = "skip-validation" + skipImageScanFlag = "skip-image-scan" + publishBranchFlag = "git-publish" + buildImagesFlag = "build-images" + + imageRegistryFlag = "dev-registry" + + // Configuration flags for the release publish command. + skipPublishImagesFlag = "skip-publish-images" + skipPublishGitTag = "skip-publish-git-tag" + skipPublishGithubRelease = "skip-publish-github-release" +) + +var ( + // debug controls whether or not to emit debug level logging. + debug bool + + // hashreleaseDir is the directory where hashreleases are built relative to the repo root. + hashreleaseDir = []string{"release", "_output", "hashrelease"} + + // releaseNotesDir is the directory where release notes are stored + releaseNotesDir = "release-notes" +) + +func configureLogging(filename string) { + if debug { + logrus.SetLevel(logrus.DebugLevel) + } else { + logrus.SetLevel(logrus.InfoLevel) + } + + // Set up logging to both stdout as well as a file. + writers := []io.Writer{os.Stdout, &lumberjack.Logger{ + Filename: filename, + MaxSize: 100, + MaxAge: 30, + MaxBackups: 10, + }} + logrus.SetOutput(io.MultiWriter(writers...)) +} + +// globalFlags are flags that are available to all sub-commands. +var globalFlags = []cli.Flag{ + &cli.BoolFlag{ + Name: "debug", + Aliases: []string{"d"}, + Usage: "Enable verbose log output", + Value: false, + Destination: &debug, + }, +} + +func main() { + cfg := config.LoadConfig() + runner := registry.MustDockerRunner() + + app := &cli.App{ + Name: "release", + Usage: fmt.Sprintf("a tool for building %s releases", utils.DisplayProductName()), + Flags: globalFlags, + Commands: []*cli.Command{}, + } + + // Add sub-commands below. + + // The hashrelease command suite is used to build and publish hashreleases, as well as + // to interact with the hashrelease server. + app.Commands = append(app.Commands, &cli.Command{ + Name: "hashrelease", + Aliases: []string{"hr"}, + Usage: "Build and publish hashreleases.", + Subcommands: hashreleaseSubCommands(cfg, runner), + }) + + // The release command suite is used to build and publish official Calico releases. + app.Commands = append(app.Commands, &cli.Command{ + Name: "release", + Aliases: []string{"rel"}, + Usage: "Build and publish official Calico releases.", + Subcommands: releaseSubCommands(cfg), + }) + + // The branch command suite manages branches. + app.Commands = append(app.Commands, &cli.Command{ + Name: "branch", + Aliases: []string{"br"}, + Usage: "Manage branches.", + Subcommands: branchSubCommands(cfg), + }) + + // Run the app. + if err := app.Run(os.Args); err != nil { + logrus.WithError(err).Fatal("Error running task") + } +} + +func hashreleaseSubCommands(cfg *config.Config, runner *registry.DockerRunner) []*cli.Command { + // dir is the directory where hashreleases are built. + dir := filepath.Join(append([]string{cfg.RepoRootDir}, hashreleaseDir...)...) + + return []*cli.Command{ + // The build command is used to produce a new local hashrelease in the output directory. + { + Name: "build", + Usage: "Build a hashrelease locally in _output/", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: skipValidationFlag, Usage: "Skip pre-build validation", Value: false}, + &cli.BoolFlag{Name: buildImagesFlag, Usage: "Build images from local codebase. If false, will use images from CI instead.", Value: false}, + &cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use, for development", Value: ""}, + }, + Action: func(c *cli.Context) error { + configureLogging("hashrelease-build.log") + if !c.Bool(skipValidationFlag) { + tasks.PreReleaseValidate(cfg) + } + + // Create the pinned-version.yaml file and extract the versions and hash. + ver, operatorVer, hash := tasks.PinnedVersion(cfg) + + // Check if the hashrelease has already been published. + tasks.CheckIfHashReleasePublished(cfg, hash) + + // Build the operator. + tasks.OperatorHashreleaseBuild(runner, cfg) + + // Configure a release builder using the generated versions, and use it + // to build a Calico release. + opts := []builder.Option{ + builder.WithRepoRoot(cfg.RepoRootDir), + builder.IsHashRelease(), + builder.WithVersions(ver, operatorVer), + builder.WithOutputDir(dir), + builder.WithBuildImages(c.Bool(buildImagesFlag)), + builder.WithPreReleaseValidation(!c.Bool(skipValidationFlag)), + builder.WithGithubOrg(cfg.Organization), + builder.WithArchitectures(cfg.Arches), + } + if reg := c.String(imageRegistryFlag); reg != "" { + opts = append(opts, builder.WithImageRegistries([]string{reg})) + } + + r := builder.NewReleaseBuilder(opts...) + if err := r.Build(); err != nil { + return err + } + + // For real releases, release notes are generated prior to building the release. For hash releases, + // generate a set of release notes and add them to the hashrelease directory. + tasks.ReleaseNotes(cfg, filepath.Join(dir, releaseNotesDir), version.New(ver)) + + // Adjsut the formatting of the generated outputs to match the legacy hashrelease format. + return tasks.ReformatHashrelease(cfg, dir) + }, + }, + + // The publish command is used to publish a locally built hashrelease to the hashrelease server. + { + Name: "publish", + Usage: "Publish hashrelease from _output/ to hashrelease server", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: skipValidationFlag, Usage: "Skip pre-build validation", Value: false}, + &cli.BoolFlag{Name: skipImageScanFlag, Usage: "Skip sending images to image scan service.", Value: false}, + }, + Action: func(c *cli.Context) error { + configureLogging("hashrelease-publish.log") + + // If skipValidationFlag is set, then we will also skip the image scan. Ensure the user + // has set the correct flags. + if c.Bool(skipValidationFlag) && !c.Bool(skipImageScanFlag) { + return fmt.Errorf("%s must be set if %s is set", skipImageScanFlag, skipValidationFlag) + } + + // Push the operator hashrelease first before validaion + // This is because validation checks all images exists and sends to Image Scan Service + tasks.OperatorHashreleasePush(runner, cfg) + if !c.Bool(skipValidationFlag) { + tasks.HashreleaseValidate(cfg, c.Bool(skipImageScanFlag)) + } + tasks.HashreleasePush(cfg, dir) + return nil + }, + }, + + // The garbage-collect command is used to clean up older hashreleases from the hashrelease server. + { + Name: "garbage-collect", + Usage: "Clean up older hashreleases", + Aliases: []string{"gc"}, + Action: func(c *cli.Context) error { + configureLogging("hashrelease-garbage-collect.log") + tasks.HashreleaseCleanRemote(cfg) + return nil + }, + }, + } +} + +func releaseSubCommands(cfg *config.Config) []*cli.Command { + // Base location for release uploads. Each release will get a directory + // within this location. + baseUploadDir := filepath.Join(cfg.RepoRootDir, "release", "_output", "upload") + + return []*cli.Command{ + // Build release notes prior to a release. + { + Name: "generate-release-notes", + Usage: "Generate release notes for the next release", + Action: func(c *cli.Context) error { + configureLogging("release-notes.log") + ver, err := version.DetermineReleaseVersion(version.GitVersion(), cfg.DevTagSuffix) + if err != nil { + return err + } + tasks.ReleaseNotes(cfg, filepath.Join(cfg.RepoRootDir, releaseNotesDir), ver) + return nil + }, + }, + + // Build a release. + { + Name: "build", + Usage: "Build an official Calico release", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: skipValidationFlag, Usage: "Skip pre-build validation", Value: false}, + &cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use, for development", Value: ""}, + }, + Action: func(c *cli.Context) error { + configureLogging("release-build.log") + + // Determine the versions to use for the release. + ver, err := version.DetermineReleaseVersion(version.GitVersion(), cfg.DevTagSuffix) + if err != nil { + return err + } + operatorVer, err := version.DetermineOperatorVersion(cfg.RepoRootDir) + if err != nil { + return err + } + + // Configure the builder. + opts := []builder.Option{ + builder.WithRepoRoot(cfg.RepoRootDir), + builder.WithVersions(ver.FormattedString(), operatorVer.FormattedString()), + builder.WithOutputDir(filepath.Join(baseUploadDir, ver.FormattedString())), + builder.WithArchitectures(cfg.Arches), + builder.WithGithubOrg(cfg.Organization), + } + if c.Bool(skipValidationFlag) { + opts = append(opts, builder.WithPreReleaseValidation(false)) + } + if reg := c.String(imageRegistryFlag); reg != "" { + opts = append(opts, builder.WithImageRegistries([]string{reg})) + } + r := builder.NewReleaseBuilder(opts...) + return r.Build() + }, + }, + + // Publish a release. + { + Name: "publish", + Usage: "Publish a pre-built Calico release", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: skipPublishImagesFlag, Usage: "Skip publishing of container images to registry", Value: false}, + &cli.BoolFlag{Name: skipPublishGitTag, Usage: "Skip publishing of tag to git repository", Value: false}, + &cli.BoolFlag{Name: skipPublishGithubRelease, Usage: "Skip publishing of release to Github", Value: false}, + &cli.StringFlag{Name: imageRegistryFlag, Usage: "Specify image registry to use, for development", Value: ""}, + }, + Action: func(c *cli.Context) error { + configureLogging("release-publish.log") + ver, operatorVer, err := version.VersionsFromManifests(cfg.RepoRootDir) + if err != nil { + return err + } + opts := []builder.Option{ + builder.WithRepoRoot(cfg.RepoRootDir), + builder.WithVersions(ver.FormattedString(), operatorVer.FormattedString()), + builder.WithOutputDir(filepath.Join(baseUploadDir, ver.FormattedString())), + builder.WithPublishOptions(!c.Bool(skipPublishImagesFlag), !c.Bool(skipPublishGitTag), !c.Bool(skipPublishGithubRelease)), + builder.WithGithubOrg(cfg.Organization), + } + if reg := c.String(imageRegistryFlag); reg != "" { + opts = append(opts, builder.WithImageRegistries([]string{reg})) + } + r := builder.NewReleaseBuilder(opts...) + return r.PublishRelease() + }, + }, + } +} + +func branchSubCommands(cfg *config.Config) []*cli.Command { + return []*cli.Command{ + // Cut a new branch from master. + { + Name: "cut", + Usage: "Cut a new branch from master", + Flags: []cli.Flag{ + &cli.BoolFlag{Name: publishBranchFlag, Usage: "Push branch and tag to git 'origin'. If false, all changes are local.", Value: false}, + }, + Action: func(c *cli.Context) error { + configureLogging("cut-branch.log") + opts := []builder.Option{ + builder.WithRepoRoot(cfg.RepoRootDir), + builder.WithVersions("master", "master"), + } + r := builder.NewReleaseBuilder(opts...) + return r.NewBranch(c.Bool(publishBranchFlag)) + }, + }, + } +} diff --git a/hack/release/get-contributors.py b/release/get-contributors.py similarity index 100% rename from hack/release/get-contributors.py rename to release/get-contributors.py diff --git a/hack/release/pkg/builder/commands.go b/release/internal/command/commands.go similarity index 73% rename from hack/release/pkg/builder/commands.go rename to release/internal/command/commands.go index 4f4e68c1580..831d2881762 100644 --- a/hack/release/pkg/builder/commands.go +++ b/release/internal/command/commands.go @@ -1,4 +1,4 @@ -package builder +package command import ( "bytes" @@ -32,11 +32,20 @@ func (r *RealCommandRunner) RunInDir(dir, name string, args []string, env []stri } cmd.Dir = dir var outb, errb bytes.Buffer - cmd.Stdout = io.MultiWriter(os.Stdout, &outb) - cmd.Stderr = io.MultiWriter(os.Stderr, &errb) - logrus.WithField("cmd", cmd.String()).Infof("Running %s command", name) + if logrus.IsLevelEnabled(logrus.DebugLevel) { + // If debug level is enabled, also write to stdout. + cmd.Stdout = io.MultiWriter(os.Stdout, &outb) + cmd.Stderr = io.MultiWriter(os.Stderr, &errb) + } else { + // Otherwise, just capture the output to return. + cmd.Stdout = io.MultiWriter(&outb) + cmd.Stderr = io.MultiWriter(&errb) + } + logrus.WithFields(logrus.Fields{ + "cmd": cmd.String(), + "dir": dir, + }).Infof("Running %s command", name) err := cmd.Run() - logrus.Debug(outb.String()) if err != nil { err = fmt.Errorf("%s: %s", err, strings.TrimSpace(errb.String())) } @@ -51,7 +60,10 @@ func (r *RealCommandRunner) RunInDirNoCapture(dir, name string, args []string, e cmd.Dir = dir cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - logrus.WithField("cmd", cmd.String()).Infof("Running %s command", name) + logrus.WithFields(logrus.Fields{ + "cmd": cmd.String(), + "dir": dir, + }).Infof("Running %s command", name) err := cmd.Run() return err } diff --git a/release/internal/command/git.go b/release/internal/command/git.go new file mode 100644 index 00000000000..382f4e21bbb --- /dev/null +++ b/release/internal/command/git.go @@ -0,0 +1,28 @@ +package command + +// GitInDir runs a git command in a specific directory. +func GitInDir(dir string, args ...string) (string, error) { + return runner().RunInDir(dir, "git", args, nil) +} + +// Git runs a git command. +func Git(args ...string) (string, error) { + return runner().Run("git", args, nil) +} + +func GitVersion(dir string, includeDirty bool) (string, error) { + args := []string{"describe", "--tags", "--always", "--long", "--abbrev=12"} + if includeDirty { + args = append(args, "--dirty") + } + return GitInDir(dir, args...) +} + +// GitDir returns the root directory of the git repository. +func GitDir(repoDir string) (string, error) { + args := []string{"rev-parse", "--show-toplevel"} + if repoDir != "" { + return GitInDir(repoDir, args...) + } + return Git(args...) +} diff --git a/release/internal/command/make.go b/release/internal/command/make.go new file mode 100644 index 00000000000..75e3e51c91c --- /dev/null +++ b/release/internal/command/make.go @@ -0,0 +1,12 @@ +package command + +// Make runs a make command. +func Make(args []string, envs []string) (string, error) { + return runner().Run("make", args, envs) +} + +// MakeInDir runs a make command in a specific directory. +func MakeInDir(dir string, args []string, envs []string) (string, error) { + args = append([]string{"-C", dir}, args...) + return Make(args, envs) +} diff --git a/release/internal/command/runner.go b/release/internal/command/runner.go new file mode 100644 index 00000000000..71ef7c2e5d6 --- /dev/null +++ b/release/internal/command/runner.go @@ -0,0 +1,10 @@ +package command + +func runner() CommandRunner { + return &RealCommandRunner{} +} + +// Run runs a command with arguments. +func Run(command string, args []string) (string, error) { + return runner().Run(command, args, nil) +} diff --git a/release/internal/command/ssh.go b/release/internal/command/ssh.go new file mode 100644 index 00000000000..ff98da952ae --- /dev/null +++ b/release/internal/command/ssh.go @@ -0,0 +1,90 @@ +package command + +import ( + "bytes" + "fmt" + "os" + "strings" + + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" +) + +// SSHConfig holds the configuration for an SSH connection +type SSHConfig struct { + Host string + User string + KeyPath string + Port string +} + +// NewSSHConfig creates a new SSHConfig +func NewSSHConfig(host, user, keyPath, port string) *SSHConfig { + return &SSHConfig{ + Host: host, + User: user, + KeyPath: keyPath, + Port: port, + } +} + +// Args returns the ssh command string arguments +func (s *SSHConfig) Args() string { + str := []string{"-i", s.KeyPath, "-p", s.Port, "-q", "-o StrictHostKeyChecking=no", "-o UserKnownHostsFile=/dev/null"} + return strings.Join(str, " ") +} + +// HostString returns the host string in the format user@host +func (s *SSHConfig) HostString() string { + return s.User + "@" + s.Host +} + +// Address returns the address in the format host:port +func (s *SSHConfig) Address() string { + return fmt.Sprintf("%s:%s", s.Host, s.Port) +} + +func connect(sshConfig *SSHConfig) (*ssh.Session, error) { + key, err := os.ReadFile(sshConfig.KeyPath) + if err != nil { + logrus.WithField("key", sshConfig.KeyPath).WithError(err).Error("Unable to read ssh key") + return nil, err + } + signer, err := ssh.ParsePrivateKey(key) + if err != nil { + return nil, err + } + config := &ssh.ClientConfig{ + User: sshConfig.User, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + } + client, err := ssh.Dial("tcp", sshConfig.Address(), config) + if err != nil { + return nil, err + } + session, err := client.NewSession() + if err != nil { + return nil, err + } + return session, nil +} + +// RunSSHCommand runs an a command on a remote host and returns the output +func RunSSHCommand(sshConfig *SSHConfig, command string) (string, error) { + session, err := connect(sshConfig) + if err != nil { + logrus.WithError(err).Error("Failed to connect to remote host") + return "", err + } + defer session.Close() + var stdoutBuf bytes.Buffer + session.Stdout = &stdoutBuf + logrus.WithField("command", command).Info("Running command in remote host") + if err := session.Run(command); err != nil { + return "", err + } + return stdoutBuf.String(), nil +} diff --git a/release/internal/config/config.go b/release/internal/config/config.go new file mode 100644 index 00000000000..15c0ba8947c --- /dev/null +++ b/release/internal/config/config.go @@ -0,0 +1,89 @@ +package config + +import ( + "path/filepath" + + "github.com/kelseyhightower/envconfig" + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/command" + "github.com/projectcalico/calico/release/internal/imagescanner" + "github.com/projectcalico/calico/release/internal/operator" + "github.com/projectcalico/calico/release/internal/slack" + "github.com/projectcalico/calico/release/internal/utils" +) + +type Config struct { + // Organization is the name of the organization + Organization string `envconfig:"ORGANIZATION" default:"projectcalico"` + + // RepoRootDir is the root directory for this repository + RepoRootDir string `envconfig:"REPO_ROOT"` + + // DevTagSuffix is the suffix for the development tag + DevTagSuffix string `envconfig:"DEV_TAG_SUFFIX" default:"0.dev"` + + // RepoReleaseBranchPrefix is the suffix for the release tag + RepoReleaseBranchPrefix string `envconfig:"RELEASE_BRANCH_PREFIX" default:"release"` + + // OperatorConfig is the configuration for Tigera operator + OperatorConfig operator.Config + + // Arches are the OS architectures supported for multi-arch build + Arches []string `envconfig:"ARCHES" default:"amd64,arm64,ppc64le,s390x"` + + // DocsHost is the host for the hashrelease docs + DocsHost string `envconfig:"DOCS_HOST"` + + // DocsPort is the port for the hashrelease docs + DocsPort string `envconfig:"DOCS_PORT"` + + // DocsPath is the path for the hashrelease docs + DocsUser string `envconfig:"DOCS_USER"` + + // DocsPath is the path for the hashrelease docs + DocsKey string `envconfig:"DOCS_KEY"` + + // GithubToken is the token for the GitHub API + GithubToken string `envconfig:"GITHUB_TOKEN"` + + // OutputDir is the directory for the output + OutputDir string `envconfig:"OUTPUT_DIR"` + + // SlackConfig is the configuration for Slack integration + SlackConfig slack.Config + + // ImageScannerConfig is the configuration for Image Scanning Service integration + ImageScannerConfig imagescanner.Config +} + +// TmpFolderPath returns the temporary folder path. +// This is used for temporary files during the release process +func (c *Config) TmpFolderPath() string { + return filepath.Join(c.RepoRootDir, utils.ReleaseFolderName, "tmp") +} + +// repoRootDir returns the root directory of this repository +func repoRootDir() string { + dir, err := command.GitDir("") + if err != nil { + logrus.WithError(err).Fatal("failed to get repo root dir") + } + return dir +} + +// LoadConfig loads the configuration from the environment +func LoadConfig() *Config { + config := &Config{} + envconfig.MustProcess("", config) + if config.RepoRootDir == "" { + config.RepoRootDir = repoRootDir() + } + if config.OutputDir == "" { + config.OutputDir = filepath.Join(config.RepoRootDir, utils.ReleaseFolderName, "_output") + } + if config.OperatorConfig.Dir == "" { + config.OperatorConfig.Dir = filepath.Join(config.TmpFolderPath(), "operator") + } + return config +} diff --git a/release/internal/hashrelease/hashrelease.go b/release/internal/hashrelease/hashrelease.go new file mode 100644 index 00000000000..c78cc4c32b8 --- /dev/null +++ b/release/internal/hashrelease/hashrelease.go @@ -0,0 +1,171 @@ +package hashrelease + +import ( + "bufio" + "fmt" + "path/filepath" + "regexp" + "sort" + "strings" + "time" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/command" +) + +const ( + // maxHashreleasesToKeep is the number of hashreleases to keep in the server + maxHashreleasesToKeep = 400 + + // baseDomain is the base URL of the hashrelease + baseDomain = "docs.eng.tigera.net" +) + +// hashrelease represents a hashrelease folder in server +type hashrelease struct { + // Name is the full path of the hashrelease folder + Name string + + // Time is the modified time of the hashrelease folder + Time time.Time +} + +// URL returns the URL of the hashrelease +func URL(name string) string { + return fmt.Sprintf("https://%s.%s", name, baseDomain) +} + +func remoteDocsPath(user string) string { + path := "files" + if user != "root" { + path = filepath.Join("home", "core", "disk", "docs-preview", path) + } + return "/" + path +} + +func remoteReleasesLibraryPath(user string) string { + return filepath.Join(remoteDocsPath(user), "all-releases") +} + +// Exists checks if a hashrelease exists in the server +func Exists(releaseHash string, sshConfig *command.SSHConfig) bool { + if out, err := command.RunSSHCommand(sshConfig, fmt.Sprintf("cat %s | grep %s", remoteReleasesLibraryPath(sshConfig.User), releaseHash)); err == nil { + return strings.Contains(out, releaseHash) + } + return false +} + +// Publish publishes a hashrelease to the server +func Publish(name, hash, note, stream, dir string, sshConfig *command.SSHConfig) error { + dir = dir + "/" + if _, err := command.Run("rsync", []string{"--stats", "-az", "--delete", fmt.Sprintf("--rsh=ssh %s", sshConfig.Args()), dir, fmt.Sprintf("%s:%s/%s", sshConfig.HostString(), remoteDocsPath(sshConfig.User), name)}); err != nil { + logrus.WithError(err).Error("Failed to publish hashrelease") + return err + } + if _, err := command.RunSSHCommand(sshConfig, fmt.Sprintf(`echo "%s/" > %s/latest-os/%s.txt && echo %s >> %s`, URL(name), remoteDocsPath(sshConfig.User), stream, name, remoteReleasesLibraryPath(sshConfig.User))); err != nil { + logrus.WithError(err).Error("Failed to update latest hashrelease and hashrelease library") + return err + } + return nil +} + +// listHashreleases lists all hashreleases in the server +func listHashreleases(sshConfig *command.SSHConfig) ([]hashrelease, error) { + cmd := fmt.Sprintf("ls -lt --time-style=+'%%Y-%%m-%%d %%H:%%M:%%S' %s", remoteDocsPath(sshConfig.User)) + out, err := command.RunSSHCommand(sshConfig, cmd) + if err != nil { + logrus.WithError(err).Error("Failed to get list of hashreleases") + return nil, err + } + lines := strings.Split(out, "\n") + var folders []hashrelease + // Limit to folders name which have the format YYYY-MM-DD-vX.Y- + re := regexp.MustCompile(`^[0-9]{4}-[0-9]{2}-[0-9]{2}-v[0-9]+\.[0-9]+-.*$`) + for _, line := range lines { + if len(line) == 0 { + continue + } + fields := strings.Fields(line) + if len(fields) < 7 { + continue + } + // Get the last field which is the folder name + name := fields[len(fields)-1] + time, err := time.Parse("2006-01-02 15:04:05", fmt.Sprintf("%s %s", fields[5], fields[6])) + if err != nil { + continue + } + if re.MatchString(name) { + folders = append(folders, hashrelease{ + Name: filepath.Join(remoteDocsPath(sshConfig.User), name), + Time: time, + }) + } + sort.Slice(folders, func(i, j int) bool { + return folders[i].Time.Before(folders[j].Time) + }) + } + return folders, nil +} + +func getHashreleaseLibrary(sshConfig *command.SSHConfig) (string, error) { + out, err := command.RunSSHCommand(sshConfig, fmt.Sprintf("cat %s", remoteReleasesLibraryPath(sshConfig.User))) + if err != nil { + logrus.WithError(err).Error("Failed to get hashrelease library") + return "", err + } + return out, nil +} + +func cleanHashreleaseLibrary(sshConfig *command.SSHConfig, hashreleaseNames []string) error { + library, err := getHashreleaseLibrary(sshConfig) + if err != nil { + return err + } + scanner := bufio.NewScanner(strings.NewReader(library)) + var newLibrary []string + for scanner.Scan() { + line := scanner.Text() + for _, name := range hashreleaseNames { + if !strings.Contains(line, name) { + newLibrary = append(newLibrary, line) + } + } + } + + if _, err := command.RunSSHCommand(sshConfig, fmt.Sprintf("echo \"%s\" > %s", strings.Join(newLibrary, "\n"), remoteReleasesLibraryPath(sshConfig.User))); err != nil { + logrus.WithError(err).Error("Failed to update hashrelease library") + return err + } + return nil +} + +// DeleteOld deletes old hashreleases from the server. +// The limit parameter specifies the number of hashreleases to keep +func DeleteOld(sshConfig *command.SSHConfig) error { + folders, err := listHashreleases(sshConfig) + if err != nil { + logrus.WithError(err).Error("Failed to list hashreleases") + return err + } + foldersToDelete := []string{} + if len(folders) > maxHashreleasesToKeep { + for i := 0; i < len(folders)-maxHashreleasesToKeep; i++ { + foldersToDelete = append(foldersToDelete, folders[i].Name) + } + } + if len(foldersToDelete) == 0 { + logrus.Info("No hashreleases to delete") + return nil + } + if _, err := command.RunSSHCommand(sshConfig, fmt.Sprintf("rm -rf %s", strings.Join(foldersToDelete, " "))); err != nil { + logrus.WithField("folder", strings.Join(foldersToDelete, ", ")).WithError(err).Error("Failed to delete old hashrelease") + return err + } + logrus.WithField("folders", strings.Join(foldersToDelete, ", ")).Info("Deleted old hashreleases") + if err := cleanHashreleaseLibrary(sshConfig, foldersToDelete); err != nil { + logrus.WithError(err).Warn("Failed to clean hashrelease library") + } + return nil +} diff --git a/release/internal/hashrelease/pinnedversion.go b/release/internal/hashrelease/pinnedversion.go new file mode 100644 index 00000000000..ca0cf13fec4 --- /dev/null +++ b/release/internal/hashrelease/pinnedversion.go @@ -0,0 +1,280 @@ +package hashrelease + +import ( + _ "embed" + "fmt" + "html/template" + "os" + "path/filepath" + "strings" + "time" + + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + + "github.com/projectcalico/calico/release/internal/operator" + "github.com/projectcalico/calico/release/internal/registry" + "github.com/projectcalico/calico/release/internal/utils" + "github.com/projectcalico/calico/release/internal/version" +) + +//go:embed templates/pinned-version.yaml.gotmpl +var pinnedVersionTemplateData string + +const ( + pinnedVersionFileName = "pinned-version.yaml" + operatorComponentsFileName = "components.yaml" +) + +// Component represents a component in the pinned version file. +type Component struct { + Version string `yaml:"version"` + Image string `yaml:"image,omitempty"` + Registry string `yaml:"registry,omitempty"` +} + +// ImageRef returns the image reference of the component. +func (c Component) ImageRef() registry.ImageRef { + return registry.ParseImage(c.String()) +} + +// String returns the string representation of the component. +// The string representation is in the format of registry/image:version. +func (c Component) String() string { + if c.Registry == "" { + return fmt.Sprintf("%s:%s", c.Image, c.Version) + } + return fmt.Sprintf("%s/%s:%s", c.Registry, c.Image, c.Version) +} + +type OperatorComponent struct { + Component +} + +func (c OperatorComponent) InitImage() Component { + return Component{ + Version: c.Version, + Image: fmt.Sprintf("%s-init", c.Image), + Registry: c.Registry, + } +} + +// PinnedVersionData represents the data needed to generate the pinned version file. +type PinnedVersionData struct { + ReleaseName string + BaseDomain string + ProductVersion string + Operator Component + Note string + Hash string + ReleaseBranch string +} + +// PinnedVersion represents an entry in pinned version file. +type PinnedVersion struct { + Title string `yaml:"title"` + ManifestURL string `yaml:"manifest_url"` + ReleaseName string `yaml:"release_name"` + Note string `yaml:"note"` + Hash string `yaml:"full_hash"` + TigeraOperator Component `yaml:"tigera-operator"` + Components map[string]Component `yaml:"components"` +} + +// PinnedVersionFile represents the pinned version file. +type PinnedVersionFile []PinnedVersion + +func pinnedVersionFilePath(outputDir string) string { + return filepath.Join(outputDir, pinnedVersionFileName) +} + +func operatorComponentsFilePath(outputDir string) string { + return filepath.Join(outputDir, operatorComponentsFileName) +} + +// GeneratePinnedVersionFile generates the pinned version file. +func GeneratePinnedVersionFile(rootDir, releaseBranchPrefix, devTagSuffix string, operatorConfig operator.Config, outputDir string) (string, *PinnedVersionData, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + + productBranch, err := utils.GitBranch(rootDir) + if err != nil { + return "", nil, err + } + + productVersion := version.GitVersion() + releaseName := fmt.Sprintf("%s-%s-%s", time.Now().Format("2006-01-02"), version.DeterminePublishStream(productBranch, string(productVersion)), RandomWord()) + releaseName = strings.ReplaceAll(releaseName, ".", "-") + operatorBranch, err := operator.GitBranch(operatorConfig.Dir) + if err != nil { + return "", nil, err + } + operatorVersion, err := operator.GitVersion(operatorConfig.Dir) + if err != nil { + return "", nil, err + } + tmpl, err := template.New("pinnedversion").Parse(pinnedVersionTemplateData) + if err != nil { + return "", nil, err + } + data := &PinnedVersionData{ + ReleaseName: releaseName, + BaseDomain: baseDomain, + ProductVersion: productVersion.FormattedString(), + Operator: Component{ + Version: operatorVersion + "-" + releaseName, + Image: operatorConfig.Image, + Registry: operatorConfig.Registry, + }, + Hash: productVersion.FormattedString() + "-" + operatorVersion, + Note: fmt.Sprintf("%s - generated at %s using %s release branch with %s operator branch", + releaseName, time.Now().Format(time.RFC1123), productBranch, operatorBranch), + ReleaseBranch: productVersion.ReleaseBranch(releaseBranchPrefix), + } + logrus.WithField("file", pinnedVersionPath).Info("Generating pinned-version.yaml") + pinnedVersionFile, err := os.Create(pinnedVersionPath) + if err != nil { + return "", nil, err + } + defer pinnedVersionFile.Close() + if err := tmpl.Execute(pinnedVersionFile, data); err != nil { + return "", nil, err + } + + return pinnedVersionPath, data, nil +} + +// GenerateComponentsVersionFile generates the components-version.yaml for operator. +func GenerateComponentsVersionFile(outputDir string) (string, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + logrus.WithField("file", pinnedVersionPath).Info("Generating components-version.yaml for operator") + var pinnedversion PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return "", err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil { + return "", err + } + operatorComponentsFilePath := operatorComponentsFilePath(outputDir) + operatorComponentsFile, err := os.Create(operatorComponentsFilePath) + if err != nil { + return "", err + } + defer operatorComponentsFile.Close() + if err = yaml.NewEncoder(operatorComponentsFile).Encode(pinnedversion[0]); err != nil { + return "", err + } + return operatorComponentsFilePath, nil +} + +// RetrievePinnedVersion retrieves the pinned version from the pinned version file. +func RetrievePinnedVersion(outputDir string) (PinnedVersion, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedVersionFile PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return PinnedVersion{}, err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedVersionFile); err != nil { + return PinnedVersion{}, err + } + return pinnedVersionFile[0], nil +} + +// RetrievePinnedOperatorVersion retrieves the operator version from the pinned version file. +func RetrievePinnedOperator(outputDir string) (OperatorComponent, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedVersionFile PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return OperatorComponent{}, err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedVersionFile); err != nil { + return OperatorComponent{}, err + } + return OperatorComponent{ + Component: pinnedVersionFile[0].TigeraOperator, + }, nil +} + +// RetrievePinnedOperatorVersion retrieves the operator version from the pinned version file. +func RetrievePinnedOperatorVersion(outputDir string) (string, error) { + operator, err := RetrievePinnedOperator(outputDir) + if err != nil { + return "", err + } + return operator.Version, nil +} + +// RetrieveReleaseName retrieves the release name from the pinned version file. +func RetrieveReleaseName(outputDir string) (string, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedversion PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return "", err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil { + return "", err + } + return pinnedversion[0].ReleaseName, nil +} + +// RetrievePinnedProductVersion retrieves the product version from the pinned version file. +func RetrievePinnedProductVersion(outputDir string) (string, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedversion PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return "", err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil { + return "", err + } + return pinnedversion[0].Title, nil +} + +// RetrievePinnedVersionNote retrieves the note from the pinned version file. +func RetrievePinnedVersionNote(outputDir string) (string, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedversion PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return "", err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil { + return "", err + } + return pinnedversion[0].Note, nil +} + +// RetrievePinnedVersionHash retrieves the hash from the pinned version file. +func RetrievePinnedVersionHash(outputDir string) (string, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedversion PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return "", err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil { + return "", err + } + return pinnedversion[0].Hash, nil +} + +// RetrieveComponentsToValidate retrieves the components to validate from the pinned version file. +func RetrieveComponentsToValidate(outputDir string) (map[string]Component, error) { + pinnedVersionPath := pinnedVersionFilePath(outputDir) + var pinnedversion PinnedVersionFile + if pinnedVersionData, err := os.ReadFile(pinnedVersionPath); err != nil { + return nil, err + } else if err := yaml.Unmarshal([]byte(pinnedVersionData), &pinnedversion); err != nil { + return nil, err + } + components := pinnedversion[0].Components + operator := OperatorComponent{Component: pinnedversion[0].TigeraOperator} + components[operator.Image] = operator.Component + initImage := operator.InitImage() + components[initImage.Image] = operator.InitImage() + for name, component := range components { + // Skip components that do not produce images. + if name == "calico" || name == "calico/api" || name == "networking-calico" { + delete(components, name) + continue + } + img := registry.ImageMap[name] + if img != "" { + component.Image = img + } else if component.Image == "" { + component.Image = name + } + components[name] = component + } + return components, nil +} diff --git a/release/internal/hashrelease/templates/pinned-version.yaml.gotmpl b/release/internal/hashrelease/templates/pinned-version.yaml.gotmpl new file mode 100644 index 00000000000..5630171efb3 --- /dev/null +++ b/release/internal/hashrelease/templates/pinned-version.yaml.gotmpl @@ -0,0 +1,46 @@ +- title: {{.ProductVersion}} + manifests_url: https://{{.ReleaseName}}.{{.BaseDomain}} + release_name: {{.ReleaseName}} + note: {{.Note}} + full_hash: {{.Hash}} + tigera-operator: + version: {{.Operator.Version}} + image: {{.Operator.Image}} + registry: {{.Operator.Registry}} + components: + calico: + version: {{.ProductVersion}} + typha: + version: {{.ProductVersion}} + calicoctl: + version: {{.ProductVersion}} + calico/node: + version: {{.ProductVersion}} + calico/cni: + version: {{.ProductVersion}} + calico/apiserver: + version: {{.ProductVersion}} + image: calico/apiserver + calico/kube-controllers: + version: {{.ProductVersion}} + calico/api: + version: {{.ProductVersion}} + networking-calico: + version: {{.ReleaseBranch}} + flannel: + version: v0.12.0 + registry: quay.io + calico/dikastes: + version: {{.ProductVersion}} + flexvol: + version: {{.ProductVersion}} + key-cert-provisioner: + version: {{.ProductVersion}} + calico/csi: + version: {{.ProductVersion}} + csi-node-driver-registrar: + version: {{.ProductVersion}} + calico/cni-windows: + version: {{.ProductVersion}} + calico/node-windows: + version: {{.ProductVersion}} diff --git a/release/internal/hashrelease/wordlist.go b/release/internal/hashrelease/wordlist.go new file mode 100644 index 00000000000..c92e5cfe954 --- /dev/null +++ b/release/internal/hashrelease/wordlist.go @@ -0,0 +1,532 @@ +package hashrelease + +import ( + "math/rand" +) + +var wordList = []string{ + "abacus", "abdomen", "abdominal", "abide", "abiding", "ability", "ablaze", "able", "abnormal", "abrasion", "abrasive", "abreast", "abridge", "abroad", "abruptly", + "absence", "absentee", "absently", "absinthe", "absolute", "absolve", "abstain", "abstract", "absurd", "accent", "acclaim", "acclimate", "accompany", "account", "accuracy", + "accurate", "accustom", "acetone", "achiness", "aching", "acid", "acorn", "acquaint", "acquire", "acre", "acrobat", "acronym", "acting", "action", "activate", + "activator", "active", "activism", "activist", "activity", "actress", "acts", "acutely", "acuteness", "aeration", "aerobics", "aerosol", "aerospace", "afar", "affair", + "affected", "affecting", "affection", "affidavit", "affiliate", "affirm", "affix", "afflicted", "affluent", "afford", "affront", "aflame", "afloat", "aflutter", "afoot", + "afraid", "afterglow", "afterlife", "aftermath", "aftermost", "afternoon", "aged", "ageless", "agency", "agenda", "agent", "aggregate", "aghast", "agile", "agility", + "aging", "agnostic", "agonize", "agonizing", "agony", "agreeable", "agreeably", "agreed", "agreeing", "agreement", "aground", "ahead", "ahoy", "aide", "aids", + "aim", "ajar", "alabaster", "alarm", "albatross", "album", "alfalfa", "algebra", "algorithm", "alias", "alibi", "alienable", "alienate", "aliens", "alike", + "alive", "alkaline", "alkalize", "almanac", "almighty", "almost", "aloe", "aloft", "aloha", "alone", "alongside", "aloof", "alphabet", "alright", "although", + "altitude", "alto", "aluminum", "alumni", "always", "amaretto", "amaze", "amazingly", "amber", "ambiance", "ambiguity", "ambiguous", "ambition", "ambitious", "ambulance", + "ambush", "amendable", "amendment", "amends", "amenity", "amiable", "amicably", "amid", "amigo", "amino", "amiss", "ammonia", "ammonium", "amnesty", "amniotic", + "among", "amount", "amperage", "ample", "amplifier", "amplify", "amply", "amuck", "amulet", "amusable", "amused", "amusement", "amuser", "amusing", "anaconda", + "anaerobic", "anagram", "anatomist", "anatomy", "anchor", "anchovy", "ancient", "android", "anemia", "anemic", "aneurism", "anew", "angelfish", "angelic", "anger", + "angled", "angler", "angles", "angling", "angrily", "angriness", "anguished", "angular", "animal", "animate", "animating", "animation", "animator", "anime", "animosity", + "ankle", "annex", "annotate", "announcer", "annoying", "annually", "annuity", "anointer", "another", "answering", "antacid", "antarctic", "anteater", "antelope", "antennae", + "anthem", "anthill", "anthology", "antibody", "antics", "antidote", "antihero", "antiquely", "antiques", "antiquity", "antirust", "antitoxic", "antitrust", "antiviral", "antivirus", + "antler", "antonym", "antsy", "anvil", "anybody", "anyhow", "anymore", "anyone", "anyplace", "anything", "anytime", "anyway", "anywhere", "aorta", "apache", + "apostle", "appealing", "appear", "appease", "appeasing", "appendage", "appendix", "appetite", "appetizer", "applaud", "applause", "apple", "appliance", "applicant", "applied", + "apply", "appointee", "appraisal", "appraiser", "apprehend", "approach", "approval", "approve", "apricot", "april", "apron", "aptitude", "aptly", "aqua", "aqueduct", + "arbitrary", "arbitrate", "ardently", "area", "arena", "arguable", "arguably", "argue", "arise", "armadillo", "armband", "armchair", "armed", "armful", "armhole", + "arming", "armless", "armoire", "armored", "armory", "armrest", "army", "aroma", "arose", "around", "arousal", "arrange", "array", "arrest", "arrival", + "arrive", "arrogance", "arrogant", "arson", "art", "ascend", "ascension", "ascent", "ascertain", "ashamed", "ashen", "ashes", "ashy", "aside", "askew", + "asleep", "asparagus", "aspect", "aspirate", "aspire", "aspirin", "astonish", "astound", "astride", "astrology", "astronaut", "astronomy", "astute", "atlantic", "atlas", + "atom", "atonable", "atop", "atrium", "atrocious", "atrophy", "attach", "attain", "attempt", "attendant", "attendee", "attention", "attentive", "attest", "attic", + "attire", "attitude", "attractor", "attribute", "atypical", "auction", "audacious", "audacity", "audible", "audibly", "audience", "audio", "audition", "augmented", "august", + "authentic", "author", "autism", "autistic", "autograph", "automaker", "automated", "automatic", "autopilot", "available", "avalanche", "avatar", "avenge", "avenging", "avenue", + "average", "aversion", "avert", "aviation", "aviator", "avid", "avoid", "await", "awaken", "award", "aware", "awhile", "awkward", "awning", "awoke", + "awry", "axis", "babble", "babbling", "babied", "baboon", "backache", "backboard", "backboned", "backdrop", "backed", "backer", "backfield", "backfire", "backhand", + "backing", "backlands", "backlash", "backless", "backlight", "backlit", "backlog", "backpack", "backpedal", "backrest", "backroom", "backshift", "backside", "backslid", "backspace", + "backspin", "backstab", "backstage", "backtalk", "backtrack", "backup", "backward", "backwash", "backwater", "backyard", "bacon", "bacteria", "bacterium", "badass", "badge", + "badland", "badly", "badness", "baffle", "baffling", "bagel", "bagful", "baggage", "bagged", "baggie", "bagginess", "bagging", "baggy", "bagpipe", "baguette", + "baked", "bakery", "bakeshop", "baking", "balance", "balancing", "balcony", "balmy", "balsamic", "bamboo", "banana", "banish", "banister", "banjo", "bankable", + "bankbook", "banked", "banker", "banking", "banknote", "bankroll", "banner", "bannister", "banshee", "banter", "barbecue", "barbed", "barbell", "barber", "barcode", + "barge", "bargraph", "barista", "baritone", "barley", "barmaid", "barman", "barn", "barometer", "barrack", "barracuda", "barrel", "barrette", "barricade", "barrier", + "barstool", "bartender", "barterer", "bash", "basically", "basics", "basil", "basin", "basis", "basket", "batboy", "batch", "bath", "baton", "bats", + "battalion", "battered", "battering", "battery", "batting", "battle", "bauble", "bazooka", "blabber", "bladder", "blade", "blah", "blame", "blaming", "blanching", + "blandness", "blank", "blaspheme", "blasphemy", "blast", "blatancy", "blatantly", "blazer", "blazing", "bleach", "bleak", "bleep", "blemish", "blend", "bless", + "blighted", "blimp", "bling", "blinked", "blinker", "blinking", "blinks", "blip", "blissful", "blitz", "blizzard", "bloated", "bloating", "blob", "blog", + "bloomers", "blooming", "blooper", "blot", "blouse", "blubber", "bluff", "bluish", "blunderer", "blunt", "blurb", "blurred", "blurry", "blurt", "blush", + "blustery", "boaster", "boastful", "boasting", "boat", "bobbed", "bobbing", "bobble", "bobcat", "bobsled", "bobtail", "bodacious", "body", "bogged", "boggle", + "bogus", "boil", "bok", "bolster", "bolt", "bonanza", "bonded", "bonding", "bondless", "boned", "bonehead", "boneless", "bonelike", "boney", "bonfire", + "bonnet", "bonsai", "bonus", "bony", "boogeyman", "boogieman", "book", "boondocks", "booted", "booth", "bootie", "booting", "bootlace", "bootleg", "boots", + "boozy", "borax", "boring", "borough", "borrower", "borrowing", "boss", "botanical", "botanist", "botany", "botch", "both", "bottle", "bottling", "bottom", + "bounce", "bouncing", "bouncy", "bounding", "boundless", "bountiful", "bovine", "boxcar", "boxer", "boxing", "boxlike", "boxy", "breach", "breath", "breeches", + "breeching", "breeder", "breeding", "breeze", "breezy", "brethren", "brewery", "brewing", "briar", "bribe", "brick", "bride", "bridged", "brigade", "bright", + "brilliant", "brim", "bring", "brink", "brisket", "briskly", "briskness", "bristle", "brittle", "broadband", "broadcast", "broaden", "broadly", "broadness", "broadside", + "broadways", "broiler", "broiling", "broken", "broker", "bronchial", "bronco", "bronze", "bronzing", "brook", "broom", "brought", "browbeat", "brownnose", "browse", + "browsing", "bruising", "brunch", "brunette", "brunt", "brush", "brussels", "brute", "brutishly", "bubble", "bubbling", "bubbly", "buccaneer", "bucked", "bucket", + "buckle", "buckshot", "buckskin", "bucktooth", "buckwheat", "buddhism", "buddhist", "budding", "buddy", "budget", "buffalo", "buffed", "buffer", "buffing", "buffoon", + "buggy", "bulb", "bulge", "bulginess", "bulgur", "bulk", "bulldog", "bulldozer", "bullfight", "bullfrog", "bullhorn", "bullion", "bullish", "bullpen", "bullring", + "bullseye", "bullwhip", "bully", "bunch", "bundle", "bungee", "bunion", "bunkbed", "bunkhouse", "bunkmate", "bunny", "bunt", "busboy", "bush", "busily", + "busload", "bust", "busybody", "buzz", "cabana", "cabbage", "cabbie", "cabdriver", "cable", "caboose", "cache", "cackle", "cacti", "cactus", "caddie", + "caddy", "cadet", "cadillac", "cadmium", "cage", "cahoots", "cake", "calamari", "calamity", "calcium", "calculate", "calculus", "caliber", "calibrate", "calm", + "caloric", "calorie", "calzone", "camcorder", "cameo", "camera", "camisole", "camper", "campfire", "camping", "campsite", "campus", "canal", "canary", "cancel", + "candied", "candle", "candy", "cane", "canine", "canister", "cannabis", "canned", "canning", "cannon", "cannot", "canola", "canon", "canopener", "canopy", + "canteen", "canyon", "capable", "capably", "capacity", "cape", "capillary", "capital", "capitol", "capped", "capricorn", "capsize", "capsule", "caption", "captivate", + "captive", "captivity", "capture", "caramel", "carat", "caravan", "carbon", "cardboard", "carded", "cardiac", "cardigan", "cardinal", "cardstock", "carefully", "caregiver", + "careless", "caress", "caretaker", "cargo", "caring", "carless", "carload", "carmaker", "carnage", "carnation", "carnival", "carnivore", "carol", "carpenter", "carpentry", + "carpool", "carport", "carried", "carrot", "carrousel", "carry", "cartel", "cartload", "carton", "cartoon", "cartridge", "cartwheel", "carve", "carving", "carwash", + "cascade", "case", "cash", "casing", "casino", "casket", "cassette", "casually", "casualty", "catacomb", "catalog", "catalyst", "catalyze", "catapult", "cataract", + "catatonic", "catcall", "catchable", "catcher", "catching", "catchy", "caterer", "catering", "catfight", "catfish", "cathedral", "cathouse", "catlike", "catnap", "catnip", + "catsup", "cattail", "cattishly", "cattle", "catty", "catwalk", "caucasian", "caucus", "causal", "causation", "cause", "causing", "cauterize", "caution", "cautious", + "cavalier", "cavalry", "caviar", "cavity", "cedar", "celery", "celestial", "celibacy", "celibate", "celtic", "cement", "census", "ceramics", "ceremony", "certainly", + "certainty", "certified", "certify", "cesarean", "cesspool", "chafe", "chaffing", "chain", "chair", "chalice", "challenge", "chamber", "chamomile", "champion", "chance", + "change", "channel", "chant", "chaos", "chaperone", "chaplain", "chapped", "chaps", "chapter", "character", "charbroil", "charcoal", "charger", "charging", "chariot", + "charity", "charm", "charred", "charter", "charting", "chase", "chasing", "chaste", "chastise", "chastity", "chatroom", "chatter", "chatting", "chatty", "cheating", + "cheddar", "cheek", "cheer", "cheese", "cheesy", "chef", "chemicals", "chemist", "chemo", "cherisher", "cherub", "chess", "chest", "chevron", "chevy", + "chewable", "chewer", "chewing", "chewy", "chief", "chihuahua", "childcare", "childhood", "childish", "childless", "childlike", "chili", "chill", "chimp", "chip", + "chirping", "chirpy", "chitchat", "chivalry", "chive", "chloride", "chlorine", "choice", "chokehold", "choking", "chomp", "chooser", "choosing", "choosy", "chop", + "chosen", "chowder", "chowtime", "chrome", "chubby", "chuck", "chug", "chummy", "chump", "chunk", "churn", "chute", "cider", "cilantro", "cinch", + "cinema", "cinnamon", "circle", "circling", "circular", "circulate", "circus", "citable", "citadel", "citation", "citizen", "citric", "citrus", "city", "civic", + "civil", "clad", "claim", "clambake", "clammy", "clamor", "clamp", "clamshell", "clang", "clanking", "clapped", "clapper", "clapping", "clarify", "clarinet", + "clarity", "clash", "clasp", "class", "clatter", "clause", "clavicle", "claw", "clay", "clean", "clear", "cleat", "cleaver", "cleft", "clench", + "clergyman", "clerical", "clerk", "clever", "clicker", "client", "climate", "climatic", "cling", "clinic", "clinking", "clip", "clique", "cloak", "clobber", + "clock", "clone", "cloning", "closable", "closure", "clothes", "clothing", "cloud", "clover", "clubbed", "clubbing", "clubhouse", "clump", "clumsily", "clumsy", + "clunky", "clustered", "clutch", "clutter", "coach", "coagulant", "coastal", "coaster", "coasting", "coastland", "coastline", "coat", "coauthor", "cobalt", "cobbler", + "cobweb", "cocoa", "coconut", "cod", "coeditor", "coerce", "coexist", "coffee", "cofounder", "cognition", "cognitive", "cogwheel", "coherence", "coherent", "cohesive", + "coil", "coke", "cola", "cold", "coleslaw", "coliseum", "collage", "collapse", "collar", "collected", "collector", "collide", "collie", "collision", "colonial", + "colonist", "colonize", "colony", "colossal", "colt", "coma", "come", "comfort", "comfy", "comic", "coming", "comma", "commence", "commend", "comment", + "commerce", "commode", "commodity", "commodore", "common", "commotion", "commute", "commuting", "compacted", "compacter", "compactly", "compactor", "companion", "company", "compare", + "compel", "compile", "comply", "component", "composed", "composer", "composite", "compost", "composure", "compound", "compress", "comprised", "computer", "computing", "comrade", + "concave", "conceal", "conceded", "concept", "concerned", "concert", "conch", "concierge", "concise", "conclude", "concrete", "concur", "condense", "condiment", "condition", + "condone", "conducive", "conductor", "conduit", "cone", "confess", "confetti", "confidant", "confident", "confider", "confiding", "configure", "confined", "confining", "confirm", + "conflict", "conform", "confound", "confront", "confused", "confusing", "confusion", "congenial", "congested", "congrats", "congress", "conical", "conjoined", "conjure", "conjuror", + "connected", "connector", "consensus", "consent", "console", "consoling", "consonant", "constable", "constant", "constrain", "constrict", "construct", "consult", "consumer", "consuming", + "contact", "container", "contempt", "contend", "contented", "contently", "contents", "contest", "context", "contort", "contour", "contrite", "control", "contusion", "convene", + "convent", "copartner", "cope", "copied", "copier", "copilot", "coping", "copious", "copper", "copy", "coral", "cork", "cornball", "cornbread", "corncob", + "cornea", "corned", "corner", "cornfield", "cornflake", "cornhusk", "cornmeal", "cornstalk", "corny", "coronary", "coroner", "corporal", "corporate", "corral", "correct", + "corridor", "corrode", "corroding", "corrosive", "corsage", "corset", "cortex", "cosigner", "cosmetics", "cosmic", "cosmos", "cosponsor", "cost", "cottage", "cotton", + "couch", "cough", "could", "countable", "countdown", "counting", "countless", "country", "county", "courier", "covenant", "cover", "coveted", "coveting", "coyness", + "cozily", "coziness", "cozy", "crabbing", "crabgrass", "crablike", "crabmeat", "cradle", "cradling", "crafter", "craftily", "craftsman", "craftwork", "crafty", "cramp", + "cranberry", "crane", "cranial", "cranium", "crank", "crate", "crave", "craving", "crawfish", "crawlers", "crawling", "crayfish", "crayon", "crazed", "crazily", + "craziness", "crazy", "creamed", "creamer", "creamlike", "crease", "creasing", "creatable", "create", "creation", "creative", "creature", "credible", "credibly", "credit", + "creed", "creme", "creole", "crepe", "crept", "crescent", "crested", "cresting", "crestless", "crevice", "crewless", "crewman", "crewmate", "crib", "cricket", + "cried", "crier", "crimp", "crimson", "cringe", "cringing", "crinkle", "crinkly", "crisped", "crisping", "crisply", "crispness", "crispy", "criteria", "critter", + "croak", "crock", "crook", "croon", "crop", "cross", "crouch", "crouton", "crowbar", "crowd", "crown", "crucial", "crudely", "crudeness", "cruelly", + "cruelness", "cruelty", "crumb", "crummiest", "crummy", "crumpet", "crumpled", "cruncher", "crunching", "crunchy", "crusader", "crushable", "crushed", "crusher", "crushing", + "crust", "crux", "crying", "cryptic", "crystal", "cubbyhole", "cube", "cubical", "cubicle", "cucumber", "cuddle", "cuddly", "cufflink", "culinary", "culminate", + "culpable", "culprit", "cultivate", "cultural", "culture", "cupbearer", "cupcake", "cupid", "cupped", "cupping", "curable", "curator", "curdle", "cure", "curfew", + "curing", "curled", "curler", "curliness", "curling", "curly", "curry", "curse", "cursive", "cursor", "curtain", "curtly", "curtsy", "curvature", "curve", + "curvy", "cushy", "cusp", "cussed", "custard", "custodian", "custody", "customary", "customer", "customize", "customs", "cut", "cycle", "cyclic", "cycling", + "cyclist", "cylinder", "cymbal", "cytoplasm", "cytoplast", "dab", "dad", "daffodil", "dagger", "daily", "daintily", "dainty", "dairy", "daisy", "dallying", + "dance", "dancing", "dandelion", "dander", "dandruff", "dandy", "danger", "dangle", "dangling", "daredevil", "dares", "daringly", "darkened", "darkening", "darkish", + "darkness", "darkroom", "darling", "darn", "dart", "darwinism", "dash", "dastardly", "data", "datebook", "dating", "daughter", "daunting", "dawdler", "dawn", + "daybed", "daybreak", "daycare", "daydream", "daylight", "daylong", "dayroom", "daytime", "dazzler", "dazzling", "deacon", "deafening", "deafness", "dealer", "dealing", + "dealmaker", "dealt", "dean", "debatable", "debate", "debating", "debit", "debrief", "debtless", "debtor", "debug", "debunk", "decade", "decaf", "decal", + "decathlon", "decay", "deceased", "deceit", "deceiver", "deceiving", "december", "decency", "decent", "deception", "deceptive", "decibel", "decidable", "decimal", "decimeter", + "decipher", "deck", "declared", "decline", "decode", "decompose", "decorated", "decorator", "decoy", "decrease", "decree", "dedicate", "dedicator", "deduce", "deduct", + "deed", "deem", "deepen", "deeply", "deepness", "deface", "defacing", "defame", "default", "defeat", "defection", "defective", "defendant", "defender", "defense", + "defensive", "deferral", "deferred", "defiance", "defiant", "defile", "defiling", "define", "definite", "deflate", "deflation", "deflator", "deflected", "deflector", "defog", + "deforest", "defraud", "defrost", "deftly", "defuse", "defy", "degraded", "degrading", "degrease", "degree", "dehydrate", "deity", "dejected", "delay", "delegate", + "delegator", "delete", "deletion", "delicacy", "delicate", "delicious", "delighted", "delirious", "delirium", "deliverer", "delivery", "delouse", "delta", "deluge", "delusion", + "deluxe", "demanding", "demeaning", "demeanor", "demise", "democracy", "democrat", "demote", "demotion", "demystify", "denatured", "deniable", "denial", "denim", "denote", + "dense", "density", "dental", "dentist", "denture", "deny", "deodorant", "deodorize", "departed", "departure", "depict", "deplete", "depletion", "deplored", "deploy", + "deport", "depose", "depraved", "depravity", "deprecate", "depress", "deprive", "depth", "deputize", "deputy", "derail", "deranged", "derby", "derived", "desecrate", + "deserve", "deserving", "designate", "designed", "designer", "designing", "deskbound", "desktop", "deskwork", "desolate", "despair", "despise", "despite", "destiny", "destitute", + "destruct", "detached", "detail", "detection", "detective", "detector", "detention", "detergent", "detest", "detonate", "detonator", "detoxify", "detract", "deuce", "devalue", + "deviancy", "deviant", "deviate", "deviation", "deviator", "device", "devious", "devotedly", "devotee", "devotion", "devourer", "devouring", "devoutly", "dexterity", "dexterous", + "diabetes", "diabetic", "diabolic", "diagnoses", "diagnosis", "diagram", "dial", "diameter", "diaper", "diaphragm", "diary", "dice", "dicing", "dictate", "dictation", + "dictator", "difficult", "diffused", "diffuser", "diffusion", "diffusive", "dig", "dilation", "diligence", "diligent", "dill", "dilute", "dime", "diminish", "dimly", + "dimmed", "dimmer", "dimness", "dimple", "diner", "dingbat", "dinghy", "dinginess", "dingo", "dingy", "dining", "dinner", "diocese", "dioxide", "diploma", + "dipped", "dipper", "dipping", "directed", "direction", "directive", "directly", "directory", "direness", "dirtiness", "disabled", "disagree", "disallow", "disarm", "disarray", + "disaster", "disband", "disbelief", "disburse", "discard", "discern", "discharge", "disclose", "discolor", "discount", "discourse", "discover", "discuss", "disdain", "disengage", + "disfigure", "disgrace", "dish", "disinfect", "disjoin", "disk", "dislike", "disliking", "dislocate", "dislodge", "disloyal", "dismantle", "dismay", "dismiss", "dismount", + "disobey", "disorder", "disown", "disparate", "disparity", "dispatch", "dispense", "dispersal", "dispersed", "disperser", "displace", "display", "displease", "disposal", "dispose", + "disprove", "dispute", "disregard", "disrupt", "dissuade", "distance", "distant", "distaste", "distill", "distinct", "distort", "distract", "distress", "district", "distrust", + "ditch", "ditto", "ditzy", "dividable", "divided", "dividend", "dividers", "dividing", "divinely", "diving", "divinity", "divisible", "divisibly", "division", "divisive", + "divorcee", "dizziness", "dizzy", "doable", "docile", "dock", "doctrine", "document", "dodge", "dodgy", "doily", "doing", "dole", "dollar", "dollhouse", + "dollop", "dolly", "dolphin", "domain", "domelike", "domestic", "dominion", "dominoes", "donated", "donation", "donator", "donor", "donut", "doodle", "doorbell", + "doorframe", "doorknob", "doorman", "doormat", "doornail", "doorpost", "doorstep", "doorstop", "doorway", "doozy", "dork", "dormitory", "dorsal", "dosage", "dose", + "dotted", "doubling", "douche", "dove", "down", "dowry", "doze", "drab", "dragging", "dragonfly", "dragonish", "dragster", "drainable", "drainage", "drained", + "drainer", "drainpipe", "dramatic", "dramatize", "drank", "drapery", "drastic", "draw", "dreaded", "dreadful", "dreadlock", "dreamboat", "dreamily", "dreamland", "dreamless", + "dreamlike", "dreamt", "dreamy", "drearily", "dreary", "drench", "dress", "drew", "dribble", "dried", "drier", "drift", "driller", "drilling", "drinkable", + "drinking", "dripping", "drippy", "drivable", "driven", "driver", "driveway", "driving", "drizzle", "drizzly", "drone", "drool", "droop", "drop-down", "dropbox", + "dropkick", "droplet", "dropout", "dropper", "drove", "drown", "drowsily", "drudge", "drum", "dry", "dubbed", "dubiously", "duchess", "duckbill", "ducking", + "duckling", "ducktail", "ducky", "duct", "dude", "duffel", "dugout", "duh", "duke", "duller", "dullness", "duly", "dumping", "dumpling", "dumpster", + "duo", "dupe", "duplex", "duplicate", "duplicity", "durable", "durably", "duration", "duress", "during", "dusk", "dust", "dutiful", "duty", "duvet", + "dwarf", "dweeb", "dwelled", "dweller", "dwelling", "dwindle", "dwindling", "dynamic", "dynamite", "dynasty", "dyslexia", "dyslexic", "each", "eagle", "earache", + "eardrum", "earflap", "earful", "earlobe", "early", "earmark", "earmuff", "earphone", "earpiece", "earplugs", "earring", "earshot", "earthen", "earthlike", "earthling", + "earthly", "earthworm", "earthy", "earwig", "easeful", "easel", "easiest", "easily", "easiness", "easing", "eastbound", "eastcoast", "easter", "eastward", "eatable", + "eaten", "eatery", "eating", "eats", "ebay", "ebony", "ebook", "ecard", "eccentric", "echo", "eclair", "eclipse", "ecologist", "ecology", "economic", + "economist", "economy", "ecosphere", "ecosystem", "edge", "edginess", "edging", "edgy", "edition", "editor", "educated", "education", "educator", "eel", "effective", + "effects", "efficient", "effort", "eggbeater", "egging", "eggnog", "eggplant", "eggshell", "egomaniac", "egotism", "egotistic", "either", "eject", "elaborate", "elastic", + "elated", "elbow", "eldercare", "elderly", "eldest", "electable", "election", "elective", "elephant", "elevate", "elevating", "elevation", "elevator", "eleven", "elf", + "eligible", "eligibly", "eliminate", "elite", "elitism", "elixir", "elk", "ellipse", "elliptic", "elm", "elongated", "elope", "eloquence", "eloquent", "elsewhere", + "elude", "elusive", "elves", "email", "embargo", "embark", "embassy", "embattled", "embellish", "ember", "embezzle", "emblaze", "emblem", "embody", "embolism", + "emboss", "embroider", "emcee", "emerald", "emergency", "emission", "emit", "emote", "emoticon", "emotion", "empathic", "empathy", "emperor", "emphases", "emphasis", + "emphasize", "emphatic", "empirical", "employed", "employee", "employer", "emporium", "empower", "emptier", "emptiness", "empty", "emu", "enable", "enactment", "enamel", + "enchanted", "enchilada", "encircle", "enclose", "enclosure", "encode", "encore", "encounter", "encourage", "encroach", "encrust", "encrypt", "endanger", "endeared", "endearing", + "ended", "ending", "endless", "endnote", "endocrine", "endorphin", "endorse", "endowment", "endpoint", "endurable", "endurance", "enduring", "energetic", "energize", "energy", + "enforced", "enforcer", "engaged", "engaging", "engine", "engorge", "engraved", "engraver", "engraving", "engross", "engulf", "enhance", "enigmatic", "enjoyable", "enjoyably", + "enjoyer", "enjoying", "enjoyment", "enlarged", "enlarging", "enlighten", "enlisted", "enquirer", "enrage", "enrich", "enroll", "enslave", "ensnare", "ensure", "entail", + "entangled", "entering", "entertain", "enticing", "entire", "entitle", "entity", "entomb", "entourage", "entrap", "entree", "entrench", "entrust", "entryway", "entwine", + "enunciate", "envelope", "enviable", "enviably", "envious", "envision", "envoy", "envy", "enzyme", "epic", "epidemic", "epidermal", "epidermis", "epidural", "epilepsy", + "epileptic", "epilogue", "epiphany", "episode", "equal", "equate", "equation", "equator", "equinox", "equipment", "equity", "equivocal", "eradicate", "erasable", "erased", + "eraser", "erasure", "ergonomic", "errand", "errant", "erratic", "error", "erupt", "escalate", "escalator", "escapable", "escapade", "escapist", "escargot", "eskimo", + "esophagus", "espionage", "espresso", "esquire", "essay", "essence", "essential", "establish", "estate", "esteemed", "estimate", "estimator", "estranged", "estrogen", "etching", + "eternal", "eternity", "ethanol", "ether", "ethically", "ethics", "euphemism", "evacuate", "evacuee", "evade", "evaluate", "evaluator", "evaporate", "evasion", "evasive", + "even", "everglade", "evergreen", "everybody", "everyday", "everyone", "evict", "evidence", "evident", "evil", "evoke", "evolution", "evolve", "exact", "exalted", + "example", "excavate", "excavator", "exceeding", "exception", "excess", "exchange", "excitable", "exciting", "exclaim", "exclude", "excluding", "exclusion", "exclusive", "excretion", + "excretory", "excursion", "excusable", "excusably", "excuse", "exemplary", "exemplify", "exemption", "exerciser", "exert", "exes", "exfoliate", "exhale", "exhaust", "exhume", + "exile", "existing", "exit", "exodus", "exonerate", "exorcism", "exorcist", "expand", "expanse", "expansion", "expansive", "expectant", "expedited", "expediter", "expel", + "expend", "expenses", "expensive", "expert", "expire", "expiring", "explain", "expletive", "explicit", "explode", "exploit", "explore", "exploring", "exponent", "exporter", + "exposable", "expose", "exposure", "express", "expulsion", "exquisite", "extended", "extending", "extent", "extenuate", "exterior", "external", "extinct", "extortion", "extradite", + "extras", "extrovert", "extrude", "extruding", "exuberant", "fable", "fabric", "fabulous", "facebook", "facecloth", "facedown", "faceless", "facelift", "faceplate", "faceted", + "facial", "facility", "facing", "facsimile", "faction", "factoid", "factor", "factsheet", "factual", "faculty", "fade", "fading", "failing", "falcon", "fall", + "false", "falsify", "fame", "familiar", "family", "famine", "famished", "fanatic", "fancied", "fanciness", "fancy", "fanfare", "fang", "fanning", "fantasize", + "fantastic", "fantasy", "fascism", "fastball", "faster", "fasting", "fastness", "faucet", "favorable", "favorably", "favored", "favoring", "favorite", "fax", "feast", + "federal", "fedora", "feeble", "feed", "feel", "feisty", "feline", "felt-tip", "feminine", "feminism", "feminist", "feminize", "femur", "fence", "fencing", + "fender", "ferment", "fernlike", "ferocious", "ferocity", "ferret", "ferris", "ferry", "fervor", "fester", "festival", "festive", "festivity", "fetal", "fetch", + "fever", "fiber", "fiction", "fiddle", "fiddling", "fidelity", "fidgeting", "fidgety", "fifteen", "fifth", "fiftieth", "fifty", "figment", "figure", "figurine", + "filing", "filled", "filler", "filling", "film", "filter", "filth", "filtrate", "finale", "finalist", "finalize", "finally", "finance", "financial", "finch", + "fineness", "finer", "finicky", "finished", "finisher", "finishing", "finite", "finless", "finlike", "fiscally", "fit", "five", "flaccid", "flagman", "flagpole", + "flagship", "flagstick", "flagstone", "flail", "flakily", "flaky", "flame", "flammable", "flanked", "flanking", "flannels", "flap", "flaring", "flashback", "flashbulb", + "flashcard", "flashily", "flashing", "flashy", "flask", "flatbed", "flatfoot", "flatly", "flatness", "flatten", "flattered", "flatterer", "flattery", "flattop", "flatware", + "flatworm", "flavored", "flavorful", "flavoring", "flaxseed", "fled", "fleshed", "fleshy", "flick", "flier", "flight", "flinch", "fling", "flint", "flip", + "flirt", "float", "flock", "flogging", "flop", "floral", "florist", "floss", "flounder", "flyable", "flyaway", "flyer", "flying", "flyover", "flypaper", + "foam", "foe", "fog", "foil", "folic", "folk", "follicle", "follow", "fondling", "fondly", "fondness", "fondue", "font", "food", "fool", + "footage", "football", "footbath", "footboard", "footer", "footgear", "foothill", "foothold", "footing", "footless", "footman", "footnote", "footpad", "footpath", "footprint", + "footrest", "footsie", "footsore", "footwear", "footwork", "fossil", "foster", "founder", "founding", "fountain", "fox", "foyer", "fraction", "fracture", "fragile", + "fragility", "fragment", "fragrance", "fragrant", "frail", "frame", "framing", "frantic", "fraternal", "frayed", "fraying", "frays", "freckled", "freckles", "freebase", + "freebee", "freebie", "freedom", "freefall", "freehand", "freeing", "freeload", "freely", "freemason", "freeness", "freestyle", "freeware", "freeway", "freewill", "freezable", + "freezing", "freight", "french", "frenzied", "frenzy", "frequency", "frequent", "fresh", "fretful", "fretted", "friction", "friday", "fridge", "fried", "friend", + "frighten", "frightful", "frigidity", "frigidly", "frill", "fringe", "frisbee", "frisk", "fritter", "frivolous", "frolic", "from", "front", "frostbite", "frosted", + "frostily", "frosting", "frostlike", "frosty", "froth", "frown", "frozen", "fructose", "frugality", "frugally", "fruit", "frustrate", "frying", "gab", "gaffe", + "gag", "gainfully", "gaining", "gains", "gala", "gallantly", "galleria", "gallery", "galley", "gallon", "gallows", "gallstone", "galore", "galvanize", "gambling", + "game", "gaming", "gamma", "gander", "gangly", "gangrene", "gangway", "gap", "garage", "garbage", "garden", "gargle", "garland", "garlic", "garment", + "garnet", "garnish", "garter", "gas", "gatherer", "gathering", "gating", "gauging", "gauntlet", "gauze", "gave", "gawk", "gazing", "gear", "gecko", + "geek", "geiger", "gem", "gender", "generic", "generous", "genetics", "genre", "gentile", "gentleman", "gently", "gents", "geography", "geologic", "geologist", + "geology", "geometric", "geometry", "geranium", "gerbil", "geriatric", "germicide", "germinate", "germless", "germproof", "gestate", "gestation", "gesture", "getaway", "getting", + "getup", "giant", "gibberish", "giblet", "giddily", "giddiness", "giddy", "gift", "gigabyte", "gigahertz", "gigantic", "giggle", "giggling", "giggly", "gigolo", + "gilled", "gills", "gimmick", "girdle", "giveaway", "given", "giver", "giving", "gizmo", "gizzard", "glacial", "glacier", "glade", "gladiator", "gladly", + "glamorous", "glamour", "glance", "glancing", "glandular", "glare", "glaring", "glass", "glaucoma", "glazing", "gleaming", "gleeful", "glider", "gliding", "glimmer", + "glimpse", "glisten", "glitch", "glitter", "glitzy", "gloater", "gloating", "gloomily", "gloomy", "glorified", "glorifier", "glorify", "glorious", "glory", "gloss", + "glove", "glowing", "glowworm", "glucose", "glue", "gluten", "glutinous", "glutton", "gnarly", "gnat", "goal", "goatskin", "goes", "goggles", "going", + "goldfish", "goldmine", "goldsmith", "golf", "goliath", "gonad", "gondola", "gone", "gong", "good", "gooey", "goofball", "goofiness", "goofy", "google", + "goon", "gopher", "gore", "gorged", "gorgeous", "gory", "gosling", "gossip", "gothic", "gotten", "gout", "gown", "grab", "graceful", "graceless", + "gracious", "gradation", "graded", "grader", "gradient", "grading", "gradually", "graduate", "graffiti", "grafted", "grafting", "grain", "granddad", "grandkid", "grandly", + "grandma", "grandpa", "grandson", "granite", "granny", "granola", "grant", "granular", "grape", "graph", "grapple", "grappling", "grasp", "grass", "gratified", + "gratify", "grating", "gratitude", "gratuity", "gravel", "graveness", "graves", "graveyard", "gravitate", "gravity", "gravy", "gray", "grazing", "greasily", "greedily", + "greedless", "greedy", "green", "greeter", "greeting", "grew", "greyhound", "grid", "grief", "grievance", "grieving", "grievous", "grill", "grimace", "grimacing", + "grime", "griminess", "grimy", "grinch", "grinning", "grip", "gristle", "grit", "groggily", "groggy", "groin", "groom", "groove", "grooving", "groovy", + "grope", "ground", "grouped", "grout", "grove", "grower", "growing", "growl", "grub", "grudge", "grudging", "grueling", "gruffly", "grumble", "grumbling", + "grumbly", "grumpily", "grunge", "grunt", "guacamole", "guidable", "guidance", "guide", "guiding", "guileless", "guise", "gulf", "gullible", "gully", "gulp", + "gumball", "gumdrop", "gumminess", "gumming", "gummy", "gurgle", "gurgling", "guru", "gush", "gusto", "gusty", "gutless", "guts", "gutter", "guy", + "guzzler", "gyration", "habitable", "habitant", "habitat", "habitual", "hacked", "hacker", "hacking", "hacksaw", "had", "haggler", "haiku", "half", "halogen", + "halt", "halved", "halves", "hamburger", "hamlet", "hammock", "hamper", "hamster", "hamstring", "handbag", "handball", "handbook", "handbrake", "handcart", "handclap", + "handclasp", "handcraft", "handcuff", "handed", "handful", "handgrip", "handgun", "handheld", "handiness", "handiwork", "handlebar", "handled", "handler", "handling", "handmade", + "handoff", "handpick", "handprint", "handrail", "handsaw", "handset", "handsfree", "handshake", "handstand", "handwash", "handwork", "handwoven", "handwrite", "handyman", "hangnail", + "hangout", "hangover", "hangup", "hankering", "hankie", "hanky", "haphazard", "happening", "happier", "happiest", "happily", "happiness", "happy", "harbor", "hardcopy", + "hardcore", "hardcover", "harddisk", "hardened", "hardener", "hardening", "hardhat", "hardhead", "hardiness", "hardly", "hardness", "hardship", "hardware", "hardwired", "hardwood", + "hardy", "harmful", "harmless", "harmonica", "harmonics", "harmonize", "harmony", "harness", "harpist", "harsh", "harvest", "hash", "hassle", "haste", "hastily", + "hastiness", "hasty", "hatbox", "hatchback", "hatchery", "hatchet", "hatching", "hatchling", "hate", "hatless", "hatred", "haunt", "haven", "hazard", "hazelnut", + "hazily", "haziness", "hazing", "hazy", "headache", "headband", "headboard", "headcount", "headdress", "headed", "header", "headfirst", "headgear", "heading", "headlamp", + "headless", "headlock", "headphone", "headpiece", "headrest", "headroom", "headscarf", "headset", "headsman", "headstand", "headstone", "headway", "headwear", "heap", "heat", + "heave", "heavily", "heaviness", "heaving", "hedge", "hedging", "heftiness", "hefty", "helium", "helmet", "helper", "helpful", "helping", "helpless", "helpline", + "hemlock", "hemstitch", "hence", "henchman", "henna", "herald", "herbal", "herbicide", "herbs", "heritage", "hermit", "heroics", "heroism", "herring", "herself", + "hertz", "hesitancy", "hesitant", "hesitate", "hexagon", "hexagram", "hubcap", "huddle", "huddling", "huff", "hug", "hula", "hulk", "hull", "human", + "humble", "humbling", "humbly", "humid", "humiliate", "humility", "humming", "hummus", "humongous", "humorist", "humorless", "humorous", "humpback", "humped", "humvee", + "hunchback", "hundredth", "hunger", "hungrily", "hungry", "hunk", "hunter", "hunting", "huntress", "huntsman", "hurdle", "hurled", "hurler", "hurling", "hurray", + "hurricane", "hurried", "hurry", "hurt", "husband", "hush", "husked", "huskiness", "hut", "hybrid", "hydrant", "hydrated", "hydration", "hydrogen", "hydroxide", + "hyperlink", "hypertext", "hyphen", "hypnoses", "hypnosis", "hypnotic", "hypnotism", "hypnotist", "hypnotize", "hypocrisy", "hypocrite", "ibuprofen", "ice", "iciness", "icing", + "icky", "icon", "icy", "idealism", "idealist", "idealize", "ideally", "idealness", "identical", "identify", "identity", "ideology", "idiocy", "idiom", "idly", + "igloo", "ignition", "ignore", "iguana", "illicitly", "illusion", "illusive", "image", "imaginary", "imagines", "imaging", "imbecile", "imitate", "imitation", "immature", + "immerse", "immersion", "imminent", "immobile", "immodest", "immorally", "immortal", "immovable", "immovably", "immunity", "immunize", "impaired", "impale", "impart", "impatient", + "impeach", "impeding", "impending", "imperfect", "imperial", "impish", "implant", "implement", "implicate", "implicit", "implode", "implosion", "implosive", "imply", "impolite", + "important", "importer", "impose", "imposing", "impotence", "impotency", "impotent", "impound", "imprecise", "imprint", "imprison", "impromptu", "improper", "improve", "improving", + "improvise", "imprudent", "impulse", "impulsive", "impure", "impurity", "iodine", "iodize", "ion", "ipad", "iphone", "ipod", "irate", "irk", "iron", + "irregular", "irrigate", "irritable", "irritably", "irritant", "irritate", "islamic", "islamist", "isolated", "isolating", "isolation", "isotope", "issue", "issuing", "italicize", + "italics", "item", "itinerary", "itunes", "ivory", "ivy", "jab", "jackal", "jacket", "jackknife", "jackpot", "jailbird", "jailbreak", "jailer", "jailhouse", + "jalapeno", "jam", "janitor", "january", "jargon", "jarring", "jasmine", "jaundice", "jaunt", "java", "jawed", "jawless", "jawline", "jaws", "jaybird", + "jaywalker", "jazz", "jeep", "jeeringly", "jellied", "jelly", "jersey", "jester", "jet", "jiffy", "jigsaw", "jimmy", "jingle", "jingling", "jinx", + "jitters", "jittery", "job", "jockey", "jockstrap", "jogger", "jogging", "john", "joining", "jokester", "jokingly", "jolliness", "jolly", "jolt", "jot", + "jovial", "joyfully", "joylessly", "joyous", "joyride", "joystick", "jubilance", "jubilant", "judge", "judgingly", "judicial", "judiciary", "judo", "juggle", "juggling", + "jugular", "juice", "juiciness", "juicy", "jujitsu", "jukebox", "july", "jumble", "jumbo", "jump", "junction", "juncture", "june", "junior", "juniper", + "junkie", "junkman", "junkyard", "jurist", "juror", "jury", "justice", "justifier", "justify", "justly", "justness", "juvenile", "kabob", "kangaroo", "karaoke", + "karate", "karma", "kebab", "keenly", "keenness", "keep", "keg", "kelp", "kennel", "kept", "kerchief", "kerosene", "kettle", "kick", "kiln", + "kilobyte", "kilogram", "kilometer", "kilowatt", "kilt", "kimono", "kindle", "kindling", "kindly", "kindness", "kindred", "kinetic", "kinfolk", "king", "kinship", + "kinsman", "kinswoman", "kissable", "kisser", "kissing", "kitchen", "kite", "kitten", "kitty", "kiwi", "kleenex", "knapsack", "knee", "knelt", "knickers", + "knoll", "koala", "kooky", "kosher", "krypton", "kudos", "kung", "labored", "laborer", "laboring", "laborious", "labrador", "ladder", "ladies", "ladle", + "ladybug", "ladylike", "lagged", "lagging", "lagoon", "lair", "lake", "lance", "landed", "landfall", "landfill", "landing", "landlady", "landless", "landline", + "landlord", "landmark", "landmass", "landmine", "landowner", "landscape", "landside", "landslide", "language", "lankiness", "lanky", "lantern", "lapdog", "lapel", "lapped", + "lapping", "laptop", "lard", "large", "lark", "lash", "lasso", "last", "latch", "late", "lather", "latitude", "latrine", "latter", "latticed", + "launch", "launder", "laundry", "laurel", "lavender", "lavish", "laxative", "lazily", "laziness", "lazy", "lecturer", "left", "legacy", "legal", "legend", + "legged", "leggings", "legible", "legibly", "legislate", "lego", "legroom", "legume", "legwarmer", "legwork", "lemon", "lend", "length", "lens", "lent", + "leotard", "lesser", "letdown", "lethargic", "lethargy", "letter", "lettuce", "level", "leverage", "levers", "levitate", "levitator", "liability", "liable", "liberty", + "librarian", "library", "licking", "licorice", "lid", "life", "lifter", "lifting", "liftoff", "ligament", "likely", "likeness", "likewise", "liking", "lilac", + "lilly", "lily", "limb", "limeade", "limelight", "limes", "limit", "limping", "limpness", "line", "lingo", "linguini", "linguist", "lining", "linked", + "linoleum", "linseed", "lint", "lion", "lip", "liquefy", "liqueur", "liquid", "lisp", "list", "litigate", "litigator", "litmus", "litter", "little", + "livable", "lived", "lively", "liver", "livestock", "lividly", "living", "lizard", "lubricant", "lubricate", "lucid", "luckily", "luckiness", "luckless", "lucrative", + "ludicrous", "lugged", "lukewarm", "lullaby", "lumber", "luminance", "luminous", "lumpiness", "lumping", "lumpish", "lunacy", "lunar", "lunchbox", "luncheon", "lunchroom", + "lunchtime", "lung", "lurch", "lure", "luridness", "lurk", "lushly", "lushness", "luster", "lustfully", "lustily", "lustiness", "lustrous", "lusty", "luxurious", + "luxury", "lying", "lyrically", "lyricism", "lyricist", "lyrics", "macarena", "macaroni", "macaw", "mace", "machine", "machinist", "magazine", "magenta", "maggot", + "magical", "magician", "magma", "magnesium", "magnetic", "magnetism", "magnetize", "magnifier", "magnify", "magnitude", "magnolia", "mahogany", "maimed", "majestic", "majesty", + "majorette", "majority", "makeover", "maker", "makeshift", "making", "malformed", "malt", "mama", "mammal", "mammary", "mammogram", "manager", "managing", "manatee", + "mandarin", "mandate", "mandatory", "mandolin", "manger", "mangle", "mango", "mangy", "manhandle", "manhole", "manhood", "manhunt", "manicotti", "manicure", "manifesto", + "manila", "mankind", "manlike", "manliness", "manly", "manmade", "manned", "mannish", "manor", "manpower", "mantis", "mantra", "manual", "many", "map", + "marathon", "marauding", "marbled", "marbles", "marbling", "march", "mardi", "margarine", "margarita", "margin", "marigold", "marina", "marine", "marital", "maritime", + "marlin", "marmalade", "maroon", "married", "marrow", "marry", "marshland", "marshy", "marsupial", "marvelous", "marxism", "mascot", "masculine", "mashed", "mashing", + "massager", "masses", "massive", "mastiff", "matador", "matchbook", "matchbox", "matcher", "matching", "matchless", "material", "maternal", "maternity", "math", "mating", + "matriarch", "matrimony", "matrix", "matron", "matted", "matter", "maturely", "maturing", "maturity", "mauve", "maverick", "maximize", "maximum", "maybe", "mayday", + "mayflower", "moaner", "moaning", "mobile", "mobility", "mobilize", "mobster", "mocha", "mocker", "mockup", "modified", "modify", "modular", "modulator", "module", + "moisten", "moistness", "moisture", "molar", "molasses", "mold", "molecular", "molecule", "molehill", "mollusk", "mom", "monastery", "monday", "monetary", "monetize", + "moneybags", "moneyless", "moneywise", "mongoose", "mongrel", "monitor", "monkhood", "monogamy", "monogram", "monologue", "monopoly", "monorail", "monotone", "monotype", "monoxide", + "monsieur", "monsoon", "monstrous", "monthly", "monument", "moocher", "moodiness", "moody", "mooing", "moonbeam", "mooned", "moonlight", "moonlike", "moonlit", "moonrise", + "moonscape", "moonshine", "moonstone", "moonwalk", "mop", "morale", "morality", "morally", "morbidity", "morbidly", "morphine", "morphing", "morse", "mortality", "mortally", + "mortician", "mortified", "mortify", "mortuary", "mosaic", "mossy", "most", "mothball", "mothproof", "motion", "motivate", "motivator", "motive", "motocross", "motor", + "motto", "mountable", "mountain", "mounted", "mounting", "mourner", "mournful", "mouse", "mousiness", "moustache", "mousy", "mouth", "movable", "move", "movie", + "moving", "mower", "mowing", "much", "muck", "mud", "mug", "mulberry", "mulch", "mule", "mulled", "mullets", "multiple", "multiply", "multitask", + "multitude", "mumble", "mumbling", "mumbo", "mummified", "mummify", "mummy", "mumps", "munchkin", "mundane", "municipal", "muppet", "mural", "murkiness", "murky", + "murmuring", "muscular", "museum", "mushily", "mushiness", "mushroom", "mushy", "music", "musket", "muskiness", "musky", "mustang", "mustard", "muster", "mustiness", + "musty", "mutable", "mutate", "mutation", "mute", "mutilated", "mutilator", "mutiny", "mutt", "mutual", "muzzle", "myself", "myspace", "mystified", "mystify", + "myth", "nacho", "nag", "nail", "name", "naming", "nanny", "nanometer", "nape", "napkin", "napped", "napping", "nappy", "narrow", "nastily", + "nastiness", "national", "native", "nativity", "natural", "nature", "naturist", "nautical", "navigate", "navigator", "navy", "nearby", "nearest", "nearly", "nearness", + "neatly", "neatness", "nebula", "nebulizer", "nectar", "negate", "negation", "negative", "neglector", "negligee", "negligent", "negotiate", "nemeses", "nemesis", "neon", + "nephew", "nerd", "nervous", "nervy", "nest", "net", "neurology", "neuron", "neurosis", "neurotic", "neuter", "neutron", "never", "next", "nibble", + "nickname", "nicotine", "niece", "nifty", "nimble", "nimbly", "nineteen", "ninetieth", "ninja", "nintendo", "ninth", "nuclear", "nuclei", "nucleus", "nugget", + "nullify", "number", "numbing", "numbly", "numbness", "numeral", "numerate", "numerator", "numeric", "numerous", "nuptials", "nursery", "nursing", "nurture", "nutcase", + "nutlike", "nutmeg", "nutrient", "nutshell", "nuttiness", "nutty", "nuzzle", "nylon", "oaf", "oak", "oasis", "oat", "obedience", "obedient", "obituary", + "object", "obligate", "obliged", "oblivion", "oblivious", "oblong", "obnoxious", "oboe", "obscure", "obscurity", "observant", "observer", "observing", "obsessed", "obsession", + "obsessive", "obsolete", "obstacle", "obstinate", "obstruct", "obtain", "obtrusive", "obtuse", "obvious", "occultist", "occupancy", "occupant", "occupier", "occupy", "ocean", + "ocelot", "octagon", "octane", "october", "octopus", "ogle", "oil", "oink", "ointment", "okay", "old", "olive", "olympics", "omega", "omen", + "ominous", "omission", "omit", "omnivore", "onboard", "oncoming", "ongoing", "onion", "online", "onlooker", "only", "onscreen", "onset", "onshore", "onslaught", + "onstage", "onto", "onward", "onyx", "oops", "ooze", "oozy", "opacity", "opal", "open", "operable", "operate", "operating", "operation", "operative", + "operator", "opium", "opossum", "opponent", "oppose", "opposing", "opposite", "oppressed", "oppressor", "opt", "opulently", "osmosis", "other", "otter", "ouch", + "ought", "ounce", "outage", "outback", "outbid", "outboard", "outbound", "outbreak", "outburst", "outcast", "outclass", "outcome", "outdated", "outdoors", "outer", + "outfield", "outfit", "outflank", "outgoing", "outgrow", "outhouse", "outing", "outlast", "outlet", "outline", "outlook", "outlying", "outmatch", "outmost", "outnumber", + "outplayed", "outpost", "outpour", "output", "outrage", "outrank", "outreach", "outright", "outscore", "outsell", "outshine", "outshoot", "outsider", "outskirts", "outsmart", + "outsource", "outspoken", "outtakes", "outthink", "outward", "outweigh", "outwit", "oval", "ovary", "oven", "overact", "overall", "overarch", "overbid", "overbill", + "overbite", "overblown", "overboard", "overbook", "overbuilt", "overcast", "overcoat", "overcome", "overcook", "overcrowd", "overdraft", "overdrawn", "overdress", "overdrive", "overdue", + "overeager", "overeater", "overexert", "overfed", "overfeed", "overfill", "overflow", "overfull", "overgrown", "overhand", "overhang", "overhaul", "overhead", "overhear", "overheat", + "overhung", "overjoyed", "overkill", "overlabor", "overlaid", "overlap", "overlay", "overload", "overlook", "overlord", "overlying", "overnight", "overpass", "overpay", "overplant", + "overplay", "overpower", "overprice", "overrate", "overreach", "overreact", "override", "overripe", "overrule", "overrun", "overshoot", "overshot", "oversight", "oversized", "oversleep", + "oversold", "overspend", "overstate", "overstay", "overstep", "overstock", "overstuff", "oversweet", "overtake", "overthrow", "overtime", "overtly", "overtone", "overture", "overturn", + "overuse", "overvalue", "overview", "overwrite", "owl", "oxford", "oxidant", "oxidation", "oxidize", "oxidizing", "oxygen", "oxymoron", "oyster", "ozone", "paced", + "pacemaker", "pacific", "pacifier", "pacifism", "pacifist", "pacify", "padded", "padding", "paddle", "paddling", "padlock", "pagan", "pager", "paging", "pajamas", + "palace", "palatable", "palm", "palpable", "palpitate", "paltry", "pampered", "pamperer", "pampers", "pamphlet", "panama", "pancake", "pancreas", "panda", "pandemic", + "pang", "panhandle", "panic", "panning", "panorama", "panoramic", "panther", "pantomime", "pantry", "pants", "pantyhose", "paparazzi", "papaya", "paper", "paprika", + "papyrus", "parabola", "parachute", "parade", "paradox", "paragraph", "parakeet", "paralegal", "paralyses", "paralysis", "paralyze", "paramedic", "parameter", "paramount", "parasail", + "parasite", "parasitic", "parcel", "parched", "parchment", "pardon", "parish", "parka", "parking", "parkway", "parlor", "parmesan", "parole", "parrot", "parsley", + "parsnip", "partake", "parted", "parting", "partition", "partly", "partner", "partridge", "party", "passable", "passably", "passage", "passcode", "passenger", "passerby", + "passing", "passion", "passive", "passivism", "passover", "passport", "password", "pasta", "pasted", "pastel", "pastime", "pastor", "pastrami", "pasture", "pasty", + "patchwork", "patchy", "paternal", "paternity", "path", "patience", "patient", "patio", "patriarch", "patriot", "patrol", "patronage", "patronize", "pauper", "pavement", + "paver", "pavestone", "pavilion", "paving", "pawing", "payable", "payback", "paycheck", "payday", "payee", "payer", "paying", "payment", "payphone", "payroll", + "pebble", "pebbly", "pecan", "pectin", "peculiar", "peddling", "pediatric", "pedicure", "pedigree", "pedometer", "pegboard", "pelican", "pellet", "pelt", "pelvis", + "penalize", "penalty", "pencil", "pendant", "pending", "penholder", "penknife", "pennant", "penniless", "penny", "penpal", "pension", "pentagon", "pentagram", "pep", + "perceive", "percent", "perch", "percolate", "perennial", "perfected", "perfectly", "perfume", "periscope", "perish", "perjurer", "perjury", "perkiness", "perky", "perm", + "peroxide", "perpetual", "perplexed", "persecute", "persevere", "persuaded", "persuader", "pesky", "peso", "pessimism", "pessimist", "pester", "pesticide", "petal", "petite", + "petition", "petri", "petroleum", "petted", "petticoat", "pettiness", "petty", "petunia", "phantom", "phobia", "phoenix", "phonebook", "phoney", "phonics", "phoniness", + "phony", "phosphate", "photo", "phrase", "phrasing", "placard", "placate", "placidly", "plank", "planner", "plant", "plasma", "plaster", "plastic", "plated", + "platform", "plating", "platinum", "platonic", "platter", "platypus", "plausible", "plausibly", "playable", "playback", "player", "playful", "playgroup", "playhouse", "playing", + "playlist", "playmaker", "playmate", "playoff", "playpen", "playroom", "playset", "plaything", "playtime", "plaza", "pleading", "pleat", "pledge", "plentiful", "plenty", + "plethora", "plexiglas", "pliable", "plod", "plop", "plot", "plow", "ploy", "pluck", "plug", "plunder", "plunging", "plural", "plus", "plutonium", + "plywood", "poach", "pod", "poem", "poet", "pogo", "pointed", "pointer", "pointing", "pointless", "pointy", "poise", "poison", "poker", "poking", + "polar", "police", "policy", "polio", "polish", "politely", "polka", "polo", "polyester", "polygon", "polygraph", "polymer", "poncho", "pond", "pony", + "popcorn", "pope", "poplar", "popper", "poppy", "popsicle", "populace", "popular", "populate", "porcupine", "pork", "porous", "porridge", "portable", "portal", + "portfolio", "porthole", "portion", "portly", "portside", "poser", "posh", "posing", "possible", "possibly", "possum", "postage", "postal", "postbox", "postcard", + "posted", "poster", "posting", "postnasal", "posture", "postwar", "pouch", "pounce", "pouncing", "pound", "pouring", "pout", "powdered", "powdering", "powdery", + "power", "powwow", "pox", "praising", "prance", "prancing", "pranker", "prankish", "prankster", "prayer", "praying", "preacher", "preaching", "preachy", "preamble", + "precinct", "precise", "precision", "precook", "precut", "predator", "predefine", "predict", "preface", "prefix", "preflight", "preformed", "pregame", "pregnancy", "pregnant", + "preheated", "prelaunch", "prelaw", "prelude", "premiere", "premises", "premium", "prenatal", "preoccupy", "preorder", "prepaid", "prepay", "preplan", "preppy", "preschool", + "prescribe", "preseason", "preset", "preshow", "president", "presoak", "press", "presume", "presuming", "preteen", "pretended", "pretender", "pretense", "pretext", "pretty", + "pretzel", "prevail", "prevalent", "prevent", "preview", "previous", "prewar", "prewashed", "prideful", "pried", "primal", "primarily", "primary", "primate", "primer", + "primp", "princess", "print", "prior", "prism", "prison", "prissy", "pristine", "privacy", "private", "privatize", "prize", "proactive", "probable", "probably", + "probation", "probe", "probing", "probiotic", "problem", "procedure", "process", "proclaim", "procreate", "procurer", "prodigal", "prodigy", "produce", "product", "profane", + "profanity", "professed", "professor", "profile", "profound", "profusely", "progeny", "prognosis", "program", "progress", "projector", "prologue", "prolonged", "promenade", "prominent", + "promoter", "promotion", "prompter", "promptly", "prone", "prong", "pronounce", "pronto", "proofing", "proofread", "proofs", "propeller", "properly", "property", "proponent", + "proposal", "propose", "props", "prorate", "protector", "protegee", "proton", "prototype", "protozoan", "protract", "protrude", "proud", "provable", "proved", "proven", + "provided", "provider", "providing", "province", "proving", "provoke", "provoking", "provolone", "prowess", "prowler", "prowling", "proximity", "proxy", "prozac", "prude", + "prudishly", "prune", "pruning", "pry", "psychic", "public", "publisher", "pucker", "pueblo", "pug", "pull", "pulmonary", "pulp", "pulsate", "pulse", + "pulverize", "puma", "pumice", "pummel", "punch", "punctual", "punctuate", "punctured", "pungent", "punisher", "punk", "pupil", "puppet", "puppy", "purchase", + "pureblood", "purebred", "purely", "pureness", "purgatory", "purge", "purging", "purifier", "purify", "purist", "puritan", "purity", "purple", "purplish", "purposely", + "purr", "purse", "pursuable", "pursuant", "pursuit", "purveyor", "pushcart", "pushchair", "pusher", "pushiness", "pushing", "pushover", "pushpin", "pushup", "pushy", + "putdown", "putt", "puzzle", "puzzling", "pyramid", "pyromania", "python", "quack", "quadrant", "quail", "quaintly", "quake", "quaking", "qualified", "qualifier", + "qualify", "quality", "qualm", "quantum", "quarrel", "quarry", "quartered", "quarterly", "quarters", "quartet", "quench", "query", "quicken", "quickly", "quickness", + "quicksand", "quickstep", "quiet", "quill", "quilt", "quintet", "quintuple", "quirk", "quit", "quiver", "quizzical", "quotable", "quotation", "quote", "rabid", + "race", "racing", "racism", "rack", "racoon", "radar", "radial", "radiance", "radiantly", "radiated", "radiation", "radiator", "radio", "radish", "raffle", + "raft", "rage", "ragged", "raging", "ragweed", "raider", "railcar", "railing", "railroad", "railway", "raisin", "rake", "raking", "rally", "ramble", + "rambling", "ramp", "ramrod", "ranch", "rancidity", "random", "ranged", "ranger", "ranging", "ranked", "ranking", "ransack", "ranting", "rants", "rare", + "rarity", "rascal", "rash", "rasping", "ravage", "raven", "ravine", "raving", "ravioli", "ravishing", "reabsorb", "reach", "reacquire", "reaction", "reactive", + "reactor", "reaffirm", "ream", "reanalyze", "reappear", "reapply", "reappoint", "reapprove", "rearrange", "rearview", "reason", "reassign", "reassure", "reattach", "reawake", + "rebalance", "rebate", "rebel", "rebirth", "reboot", "reborn", "rebound", "rebuff", "rebuild", "rebuilt", "reburial", "rebuttal", "recall", "recant", "recapture", + "recast", "recede", "recent", "recess", "recharger", "recipient", "recital", "recite", "reckless", "reclaim", "recliner", "reclining", "recluse", "reclusive", "recognize", + "recoil", "recollect", "recolor", "reconcile", "reconfirm", "reconvene", "recopy", "record", "recount", "recoup", "recovery", "recreate", "rectal", "rectangle", "rectified", + "rectify", "recycled", "recycler", "recycling", "reemerge", "reenact", "reenter", "reentry", "reexamine", "referable", "referee", "reference", "refill", "refinance", "refined", + "refinery", "refining", "refinish", "reflected", "reflector", "reflex", "reflux", "refocus", "refold", "reforest", "reformat", "reformed", "reformer", "reformist", "refract", + "refrain", "refreeze", "refresh", "refried", "refueling", "refund", "refurbish", "refurnish", "refusal", "refuse", "refusing", "refutable", "refute", "regain", "regalia", + "regally", "reggae", "regime", "region", "register", "registrar", "registry", "regress", "regretful", "regroup", "regular", "regulate", "regulator", "rehab", "reheat", + "rehire", "rehydrate", "reimburse", "reissue", "reiterate", "rejoice", "rejoicing", "rejoin", "rekindle", "relapse", "relapsing", "relatable", "related", "relation", "relative", + "relax", "relay", "relearn", "release", "relenting", "reliable", "reliably", "reliance", "reliant", "relic", "relieve", "relieving", "relight", "relish", "relive", + "reload", "relocate", "relock", "reluctant", "rely", "remake", "remark", "remarry", "rematch", "remedial", "remedy", "remember", "reminder", "remindful", "remission", + "remix", "remnant", "remodeler", "remold", "remorse", "remote", "removable", "removal", "removed", "remover", "removing", "rename", "renderer", "rendering", "rendition", + "renegade", "renewable", "renewably", "renewal", "renewed", "renounce", "renovate", "renovator", "rentable", "rental", "rented", "renter", "reoccupy", "reoccur", "reopen", + "reorder", "repackage", "repacking", "repaint", "repair", "repave", "repaying", "repayment", "repeal", "repeated", "repeater", "repent", "rephrase", "replace", "replay", + "replica", "reply", "reporter", "repose", "repossess", "repost", "repressed", "reprimand", "reprint", "reprise", "reproach", "reprocess", "reproduce", "reprogram", "reps", + "reptile", "reptilian", "repugnant", "repulsion", "repulsive", "repurpose", "reputable", "reputably", "request", "require", "requisite", "reroute", "rerun", "resale", "resample", + "rescuer", "reseal", "research", "reselect", "reseller", "resemble", "resend", "resent", "reset", "reshape", "reshoot", "reshuffle", "residence", "residency", "resident", + "residual", "residue", "resigned", "resilient", "resistant", "resisting", "resize", "resolute", "resolved", "resonant", "resonate", "resort", "resource", "respect", "resubmit", + "result", "resume", "resupply", "resurface", "resurrect", "retail", "retainer", "retaining", "retake", "retaliate", "retention", "rethink", "retinal", "retired", "retiree", + "retiring", "retold", "retool", "retorted", "retouch", "retrace", "retract", "retrain", "retread", "retreat", "retrial", "retrieval", "retriever", "retry", "return", + "retying", "retype", "reunion", "reunite", "reusable", "reuse", "reveal", "reveler", "revenge", "revenue", "reverb", "revered", "reverence", "reverend", "reversal", + "reverse", "reversing", "reversion", "revert", "revisable", "revise", "revision", "revisit", "revivable", "revival", "reviver", "reviving", "revocable", "revoke", "revolt", + "revolver", "revolving", "reward", "rewash", "rewind", "rewire", "reword", "rework", "rewrap", "rewrite", "rhyme", "ribbon", "ribcage", "rice", "riches", + "richly", "richness", "rickety", "ricotta", "riddance", "ridden", "ride", "riding", "rifling", "rift", "rigging", "rigid", "rigor", "rimless", "rimmed", + "rind", "rink", "rinse", "rinsing", "riot", "ripcord", "ripeness", "ripening", "ripping", "ripple", "rippling", "riptide", "rise", "rising", "risk", + "risotto", "ritalin", "ritzy", "rival", "riverbank", "riverbed", "riverboat", "riverside", "riveter", "riveting", "roamer", "roaming", "roast", "robbing", "robe", + "robin", "robotics", "robust", "rockband", "rocker", "rocket", "rockfish", "rockiness", "rocking", "rocklike", "rockslide", "rockstar", "rocky", "rogue", "roman", + "romp", "rope", "roping", "roster", "rosy", "rotten", "rotting", "rotunda", "roulette", "rounding", "roundish", "roundness", "roundup", "roundworm", "routine", + "routing", "rover", "roving", "royal", "rubbed", "rubber", "rubbing", "rubble", "rubdown", "ruby", "ruckus", "rudder", "rug", "ruined", "rule", + "rumble", "rumbling", "rummage", "rumor", "runaround", "rundown", "runner", "running", "runny", "runt", "runway", "rupture", "rural", "ruse", "rush", + "rust", "rut", "sabbath", "sabotage", "sacrament", "sacred", "sacrifice", "sadden", "saddlebag", "saddled", "saddling", "sadly", "sadness", "safari", "safeguard", + "safehouse", "safely", "safeness", "saffron", "saga", "sage", "sagging", "saggy", "said", "saint", "sake", "salad", "salami", "salaried", "salary", + "saline", "salon", "saloon", "salsa", "salt", "salutary", "salute", "salvage", "salvaging", "salvation", "same", "sample", "sampling", "sanction", "sanctity", + "sanctuary", "sandal", "sandbag", "sandbank", "sandbar", "sandblast", "sandbox", "sanded", "sandfish", "sanding", "sandlot", "sandpaper", "sandpit", "sandstone", "sandstorm", + "sandworm", "sandy", "sanitary", "sanitizer", "sank", "santa", "sapling", "sappiness", "sappy", "sarcasm", "sarcastic", "sardine", "sash", "sasquatch", "sassy", + "satchel", "satiable", "satin", "satirical", "satisfied", "satisfy", "saturate", "saturday", "sauciness", "saucy", "sauna", "savage", "savanna", "saved", "savings", + "savior", "savor", "saxophone", "say", "scabbed", "scabby", "scalded", "scalding", "scale", "scaling", "scallion", "scallop", "scalping", "scam", "scandal", + "scanner", "scanning", "scant", "scapegoat", "scarce", "scarcity", "scarecrow", "scared", "scarf", "scarily", "scariness", "scarring", "scary", "scavenger", "scenic", + "schedule", "schematic", "scheme", "scheming", "schilling", "schnapps", "scholar", "science", "scientist", "scion", "scoff", "scolding", "scone", "scoop", "scooter", + "scope", "scorch", "scorebook", "scorecard", "scored", "scoreless", "scorer", "scoring", "scorn", "scorpion", "scotch", "scoundrel", "scoured", "scouring", "scouting", + "scouts", "scowling", "scrabble", "scraggly", "scrambled", "scrambler", "scrap", "scratch", "scrawny", "screen", "scribble", "scribe", "scribing", "scrimmage", "script", + "scroll", "scrooge", "scrounger", "scrubbed", "scrubber", "scruffy", "scrunch", "scrutiny", "scuba", "scuff", "sculptor", "sculpture", "scurvy", "scuttle", "secluded", + "secluding", "seclusion", "second", "secrecy", "secret", "sectional", "sector", "secular", "securely", "security", "sedan", "sedate", "sedation", "sedative", "sediment", + "seduce", "seducing", "segment", "seismic", "seizing", "seldom", "selected", "selection", "selective", "selector", "self", "seltzer", "semantic", "semester", "semicolon", + "semifinal", "seminar", "semisoft", "semisweet", "senate", "senator", "send", "senior", "senorita", "sensation", "sensitive", "sensitize", "sensually", "sensuous", "sepia", + "september", "septic", "septum", "sequel", "sequence", "sequester", "series", "sermon", "serotonin", "serpent", "serrated", "serve", "service", "serving", "sesame", + "sessions", "setback", "setting", "settle", "settling", "setup", "sevenfold", "seventeen", "seventh", "seventy", "severity", "shabby", "shack", "shaded", "shadily", + "shadiness", "shading", "shadow", "shady", "shaft", "shakable", "shakily", "shakiness", "shaking", "shaky", "shale", "shallot", "shallow", "shame", "shampoo", + "shamrock", "shank", "shanty", "shape", "shaping", "share", "sharpener", "sharper", "sharpie", "sharply", "sharpness", "shawl", "sheath", "shed", "sheep", + "sheet", "shelf", "shell", "shelter", "shelve", "shelving", "sherry", "shield", "shifter", "shifting", "shiftless", "shifty", "shimmer", "shimmy", "shindig", + "shine", "shingle", "shininess", "shining", "shiny", "ship", "shirt", "shivering", "shock", "shone", "shoplift", "shopper", "shopping", "shoptalk", "shore", + "shortage", "shortcake", "shortcut", "shorten", "shorter", "shorthand", "shortlist", "shortly", "shortness", "shorts", "shortwave", "shorty", "shout", "shove", "showbiz", + "showcase", "showdown", "shower", "showgirl", "showing", "showman", "shown", "showoff", "showpiece", "showplace", "showroom", "showy", "shrank", "shrapnel", "shredder", + "shredding", "shrewdly", "shriek", "shrill", "shrimp", "shrine", "shrink", "shrivel", "shrouded", "shrubbery", "shrubs", "shrug", "shrunk", "shucking", "shudder", + "shuffle", "shuffling", "shun", "shush", "shut", "shy", "siamese", "siberian", "sibling", "siding", "sierra", "siesta", "sift", "sighing", "silenced", + "silencer", "silent", "silica", "silicon", "silk", "silliness", "silly", "silo", "silt", "silver", "similarly", "simile", "simmering", "simple", "simplify", + "simply", "sincere", "sincerity", "singer", "singing", "single", "singular", "sinister", "sinless", "sinner", "sinuous", "sip", "siren", "sister", "sitcom", + "sitter", "sitting", "situated", "situation", "sixfold", "sixteen", "sixth", "sixties", "sixtieth", "sixtyfold", "sizable", "sizably", "size", "sizing", "sizzle", + "sizzling", "skater", "skating", "skedaddle", "skeletal", "skeleton", "skeptic", "sketch", "skewed", "skewer", "skid", "skied", "skier", "skies", "skiing", + "skilled", "skillet", "skillful", "skimmed", "skimmer", "skimming", "skimpily", "skincare", "skinhead", "skinless", "skinning", "skinny", "skintight", "skipper", "skipping", + "skirmish", "skirt", "skittle", "skydiver", "skylight", "skyline", "skype", "skyrocket", "skyward", "slab", "slacked", "slacker", "slacking", "slackness", "slacks", + "slain", "slam", "slander", "slang", "slapping", "slapstick", "slashed", "slashing", "slate", "slather", "slaw", "sled", "sleek", "sleep", "sleet", + "sleeve", "slept", "sliceable", "sliced", "slicer", "slicing", "slick", "slider", "slideshow", "sliding", "slighted", "slighting", "slightly", "slimness", "slimy", + "slinging", "slingshot", "slinky", "slip", "slit", "sliver", "slobbery", "slogan", "sloped", "sloping", "sloppily", "sloppy", "slot", "slouching", "slouchy", + "sludge", "slug", "slum", "slurp", "slush", "sly", "small", "smartly", "smartness", "smasher", "smashing", "smashup", "smell", "smelting", "smile", + "smilingly", "smirk", "smite", "smith", "smitten", "smock", "smog", "smoked", "smokeless", "smokiness", "smoking", "smoky", "smolder", "smooth", "smother", + "smudge", "smudgy", "smuggler", "smuggling", "smugly", "smugness", "snack", "snagged", "snaking", "snap", "snare", "snarl", "snazzy", "sneak", "sneer", + "sneeze", "sneezing", "snide", "sniff", "snippet", "snipping", "snitch", "snooper", "snooze", "snore", "snoring", "snorkel", "snort", "snout", "snowbird", + "snowboard", "snowbound", "snowcap", "snowdrift", "snowdrop", "snowfall", "snowfield", "snowflake", "snowiness", "snowless", "snowman", "snowplow", "snowshoe", "snowstorm", "snowsuit", + "snowy", "snub", "snuff", "snuggle", "snugly", "snugness", "speak", "spearfish", "spearhead", "spearman", "spearmint", "species", "specimen", "specked", "speckled", + "specks", "spectacle", "spectator", "spectrum", "speculate", "speech", "speed", "spellbind", "speller", "spelling", "spendable", "spender", "spending", "spent", "spew", + "sphere", "spherical", "sphinx", "spider", "spied", "spiffy", "spill", "spilt", "spinach", "spinal", "spindle", "spinner", "spinning", "spinout", "spinster", + "spiny", "spiral", "spirited", "spiritism", "spirits", "spiritual", "splashed", "splashing", "splashy", "splatter", "spleen", "splendid", "splendor", "splice", "splicing", + "splinter", "splotchy", "splurge", "spoilage", "spoiled", "spoiler", "spoiling", "spoils", "spoken", "spokesman", "sponge", "spongy", "sponsor", "spoof", "spookily", + "spooky", "spool", "spoon", "spore", "sporting", "sports", "sporty", "spotless", "spotlight", "spotted", "spotter", "spotting", "spotty", "spousal", "spouse", + "spout", "sprain", "sprang", "sprawl", "spray", "spree", "sprig", "spring", "sprinkled", "sprinkler", "sprint", "sprite", "sprout", "spruce", "sprung", + "spry", "spud", "spur", "sputter", "spyglass", "squabble", "squad", "squall", "squander", "squash", "squatted", "squatter", "squatting", "squeak", "squealer", + "squealing", "squeamish", "squeegee", "squeeze", "squeezing", "squid", "squiggle", "squiggly", "squint", "squire", "squirt", "squishier", "squishy", "stability", "stabilize", + "stable", "stack", "stadium", "staff", "stage", "staging", "stagnant", "stagnate", "stainable", "stained", "staining", "stainless", "stalemate", "staleness", "stalling", + "stallion", "stamina", "stammer", "stamp", "stand", "stank", "staple", "stapling", "starboard", "starch", "stardom", "stardust", "starfish", "stargazer", "staring", + "stark", "starless", "starlet", "starlight", "starlit", "starring", "starry", "starship", "starter", "starting", "startle", "startling", "startup", "starved", "starving", + "stash", "state", "static", "statistic", "statue", "stature", "status", "statute", "statutory", "staunch", "stays", "steadfast", "steadier", "steadily", "steadying", + "steam", "steed", "steep", "steerable", "steering", "steersman", "stegosaur", "stellar", "stem", "stench", "stencil", "step", "stereo", "sterile", "sterility", + "sterilize", "sterling", "sternness", "sternum", "stew", "stick", "stiffen", "stiffly", "stiffness", "stifle", "stifling", "stillness", "stilt", "stimulant", "stimulate", + "stimuli", "stimulus", "stinger", "stingily", "stinging", "stingray", "stingy", "stinking", "stinky", "stipend", "stipulate", "stir", "stitch", "stock", "stoic", + "stoke", "stole", "stomp", "stonewall", "stoneware", "stonework", "stoning", "stony", "stood", "stooge", "stool", "stoop", "stoplight", "stoppable", "stoppage", + "stopped", "stopper", "stopping", "stopwatch", "storable", "storage", "storeroom", "storewide", "storm", "stout", "stove", "stowaway", "stowing", "straddle", "straggler", + "strained", "strainer", "straining", "strangely", "stranger", "strangle", "strategic", "strategy", "stratus", "straw", "stray", "streak", "stream", "street", "strength", + "strenuous", "strep", "stress", "stretch", "strewn", "stricken", "strict", "stride", "strife", "strike", "striking", "strive", "striving", "strobe", "strode", + "stroller", "strongbox", "strongly", "strongman", "struck", "structure", "strudel", "struggle", "strum", "strung", "strut", "stubbed", "stubble", "stubbly", "stubborn", + "stucco", "stuck", "student", "studied", "studio", "study", "stuffed", "stuffing", "stuffy", "stumble", "stumbling", "stump", "stung", "stunned", "stunner", + "stunning", "stunt", "stupor", "sturdily", "sturdy", "styling", "stylishly", "stylist", "stylized", "stylus", "suave", "subarctic", "subatomic", "subdivide", "subdued", + "subduing", "subfloor", "subgroup", "subheader", "subject", "sublease", "sublet", "sublevel", "sublime", "submarine", "submerge", "submersed", "submitter", "subpanel", "subpar", + "subplot", "subprime", "subscribe", "subscript", "subsector", "subside", "subsiding", "subsidize", "subsidy", "subsoil", "subsonic", "substance", "subsystem", "subtext", "subtitle", + "subtly", "subtotal", "subtract", "subtype", "suburb", "subway", "subwoofer", "subzero", "succulent", "such", "suction", "sudden", "sudoku", "suds", "sufferer", + "suffering", "suffice", "suffix", "suffocate", "suffrage", "sugar", "suggest", "suing", "suitable", "suitably", "suitcase", "suitor", "sulfate", "sulfide", "sulfite", + "sulfur", "sulk", "sullen", "sulphate", "sulphuric", "sultry", "superbowl", "superglue", "superhero", "superior", "superjet", "superman", "supermom", "supernova", "supervise", + "supper", "supplier", "supply", "support", "supremacy", "supreme", "surcharge", "surely", "sureness", "surface", "surfacing", "surfboard", "surfer", "surgery", "surgical", + "surging", "surname", "surpass", "surplus", "surprise", "surreal", "surrender", "surrogate", "surround", "survey", "survival", "survive", "surviving", "survivor", "sushi", + "suspect", "suspend", "suspense", "sustained", "sustainer", "swab", "swaddling", "swagger", "swampland", "swan", "swapping", "swarm", "sway", "swear", "sweat", + "sweep", "swell", "swept", "swerve", "swifter", "swiftly", "swiftness", "swimmable", "swimmer", "swimming", "swimsuit", "swimwear", "swinger", "swinging", "swipe", + "swirl", "switch", "swivel", "swizzle", "swooned", "swoop", "swoosh", "swore", "sworn", "swung", "sycamore", "sympathy", "symphonic", "symphony", "symptom", + "synapse", "syndrome", "synergy", "synopses", "synopsis", "synthesis", "synthetic", "syrup", "system", "t-shirt", "tabasco", "tabby", "tableful", "tables", "tablet", + "tableware", "tabloid", "tackiness", "tacking", "tackle", "tackling", "tacky", "taco", "tactful", "tactical", "tactics", "tactile", "tactless", "tadpole", "taekwondo", + "tag", "tainted", "take", "taking", "talcum", "talisman", "tall", "talon", "tamale", "tameness", "tamer", "tamper", "tank", "tanned", "tannery", + "tanning", "tantrum", "tapeless", "tapered", "tapering", "tapestry", "tapioca", "tapping", "taps", "tarantula", "target", "tarmac", "tarnish", "tarot", "tartar", + "tartly", "tartness", "task", "tassel", "taste", "tastiness", "tasting", "tasty", "tattered", "tattle", "tattling", "tattoo", "taunt", "tavern", "thank", + "that", "thaw", "theater", "theatrics", "thee", "theft", "theme", "theology", "theorize", "thermal", "thermos", "thesaurus", "these", "thesis", "thespian", + "thicken", "thicket", "thickness", "thieving", "thievish", "thigh", "thimble", "thing", "think", "thinly", "thinner", "thinness", "thinning", "thirstily", "thirsting", + "thirsty", "thirteen", "thirty", "thong", "thorn", "those", "thousand", "thrash", "thread", "threaten", "threefold", "thrift", "thrill", "thrive", "thriving", + "throat", "throbbing", "throng", "throttle", "throwaway", "throwback", "thrower", "throwing", "thud", "thumb", "thumping", "thursday", "thus", "thwarting", "thyself", + "tiara", "tibia", "tidal", "tidbit", "tidiness", "tidings", "tidy", "tiger", "tighten", "tightly", "tightness", "tightrope", "tightwad", "tigress", "tile", + "tiling", "till", "tilt", "timid", "timing", "timothy", "tinderbox", "tinfoil", "tingle", "tingling", "tingly", "tinker", "tinkling", "tinsel", "tinsmith", + "tint", "tinwork", "tiny", "tipoff", "tipped", "tipper", "tipping", "tiptoeing", "tiptop", "tiring", "tissue", "trace", "tracing", "track", "traction", + "tractor", "trade", "trading", "tradition", "traffic", "tragedy", "trailing", "trailside", "train", "traitor", "trance", "tranquil", "transfer", "transform", "translate", + "transpire", "transport", "transpose", "trapdoor", "trapeze", "trapezoid", "trapped", "trapper", "trapping", "traps", "trash", "travel", "traverse", "travesty", "tray", + "treachery", "treading", "treadmill", "treason", "treat", "treble", "tree", "trekker", "tremble", "trembling", "tremor", "trench", "trend", "trespass", "triage", + "trial", "triangle", "tribesman", "tribunal", "tribune", "tributary", "tribute", "triceps", "trickery", "trickily", "tricking", "trickle", "trickster", "tricky", "tricolor", + "tricycle", "trident", "tried", "trifle", "trifocals", "trillion", "trilogy", "trimester", "trimmer", "trimming", "trimness", "trinity", "trio", "tripod", "tripping", + "triumph", "trivial", "trodden", "trolling", "trombone", "trophy", "tropical", "tropics", "trouble", "troubling", "trough", "trousers", "trout", "trowel", "truce", + "truck", "truffle", "trump", "trunks", "trustable", "trustee", "trustful", "trusting", "trustless", "truth", "try", "tubby", "tubeless", "tubular", "tucking", + "tuesday", "tug", "tuition", "tulip", "tumble", "tumbling", "tummy", "turban", "turbine", "turbofan", "turbojet", "turbulent", "turf", "turkey", "turmoil", + "turret", "turtle", "tusk", "tutor", "tutu", "tux", "tweak", "tweed", "tweet", "tweezers", "twelve", "twentieth", "twenty", "twerp", "twice", + "twiddle", "twiddling", "twig", "twilight", "twine", "twins", "twirl", "twistable", "twisted", "twister", "twisting", "twisty", "twitch", "twitter", "tycoon", + "tying", "tyke", "udder", "ultimate", "ultimatum", "ultra", "umbilical", "umbrella", "umpire", "unabashed", "unable", "unadorned", "unadvised", "unafraid", "unaired", + "unaligned", "unaltered", "unarmored", "unashamed", "unaudited", "unawake", "unaware", "unbaked", "unbalance", "unbeaten", "unbend", "unbent", "unbiased", "unbitten", "unblended", + "unblessed", "unblock", "unbolted", "unbounded", "unboxed", "unbraided", "unbridle", "unbroken", "unbuckled", "unbundle", "unburned", "unbutton", "uncanny", "uncapped", "uncaring", + "uncertain", "unchain", "unchanged", "uncharted", "uncheck", "uncivil", "unclad", "unclaimed", "unclamped", "unclasp", "uncle", "unclip", "uncloak", "unclog", "unclothed", + "uncoated", "uncoiled", "uncolored", "uncombed", "uncommon", "uncooked", "uncork", "uncorrupt", "uncounted", "uncouple", "uncouth", "uncover", "uncross", "uncrown", "uncrushed", + "uncured", "uncurious", "uncurled", "uncut", "undamaged", "undated", "undaunted", "undead", "undecided", "undefined", "underage", "underarm", "undercoat", "undercook", "undercut", + "underdog", "underdone", "underfed", "underfeed", "underfoot", "undergo", "undergrad", "underhand", "underline", "underling", "undermine", "undermost", "underpaid", "underpass", "underpay", + "underrate", "undertake", "undertone", "undertook", "undertow", "underuse", "underwear", "underwent", "underwire", "undesired", "undiluted", "undivided", "undocked", "undoing", "undone", + "undrafted", "undress", "undrilled", "undusted", "undying", "unearned", "unearth", "unease", "uneasily", "uneasy", "uneatable", "uneaten", "unedited", "unelected", "unending", + "unengaged", "unenvied", "unequal", "unethical", "uneven", "unexpired", "unexposed", "unfailing", "unfair", "unfasten", "unfazed", "unfeeling", "unfiled", "unfilled", "unfitted", + "unfitting", "unfixable", "unfixed", "unflawed", "unfocused", "unfold", "unfounded", "unframed", "unfreeze", "unfrosted", "unfrozen", "unfunded", "unglazed", "ungloved", "unglue", + "ungodly", "ungraded", "ungreased", "unguarded", "unguided", "unhappily", "unhappy", "unharmed", "unhealthy", "unheard", "unhearing", "unheated", "unhelpful", "unhidden", "unhinge", + "unhitched", "unholy", "unhook", "unicorn", "unicycle", "unified", "unifier", "uniformed", "uniformly", "unify", "unimpeded", "uninjured", "uninstall", "uninsured", "uninvited", + "union", "uniquely", "unisexual", "unison", "unissued", "unit", "universal", "universe", "unjustly", "unkempt", "unkind", "unknotted", "unknowing", "unknown", "unlaced", + "unlatch", "unlawful", "unleaded", "unlearned", "unleash", "unless", "unleveled", "unlighted", "unlikable", "unlimited", "unlined", "unlinked", "unlisted", "unlit", "unlivable", + "unloaded", "unloader", "unlocked", "unlocking", "unlovable", "unloved", "unlovely", "unloving", "unluckily", "unlucky", "unmade", "unmanaged", "unmanned", "unmapped", "unmarked", + "unmasked", "unmasking", "unmatched", "unmindful", "unmixable", "unmixed", "unmolded", "unmoral", "unmovable", "unmoved", "unmoving", "unnamable", "unnamed", "unnatural", "unneeded", + "unnerve", "unnerving", "unnoticed", "unopened", "unopposed", "unpack", "unpadded", "unpaid", "unpainted", "unpaired", "unpaved", "unpeeled", "unpicked", "unpiloted", "unpinned", + "unplanned", "unplanted", "unpleased", "unpledged", "unplowed", "unplug", "unpopular", "unproven", "unquote", "unranked", "unrated", "unraveled", "unreached", "unread", "unreal", + "unreeling", "unrefined", "unrelated", "unrented", "unrest", "unretired", "unrevised", "unrigged", "unripe", "unrivaled", "unroasted", "unrobed", "unroll", "unruffled", "unruly", + "unrushed", "unsaddle", "unsafe", "unsaid", "unsalted", "unsaved", "unsavory", "unscathed", "unscented", "unscrew", "unsealed", "unseated", "unsecured", "unseeing", "unseemly", + "unseen", "unselect", "unselfish", "unsent", "unsettled", "unshackle", "unshaken", "unshaved", "unshaven", "unsheathe", "unshipped", "unsightly", "unsigned", "unskilled", "unsliced", + "unsmooth", "unsnap", "unsocial", "unsoiled", "unsold", "unsolved", "unsorted", "unspoiled", "unspoken", "unstable", "unstaffed", "unstamped", "unsteady", "unsterile", "unstirred", + "unstitch", "unstopped", "unstuck", "unstuffed", "unstylish", "unsubtle", "unsubtly", "unsuited", "unsure", "unsworn", "untagged", "untainted", "untaken", "untamed", "untangled", + "untapped", "untaxed", "unthawed", "unthread", "untidy", "untie", "until", "untimed", "untimely", "untitled", "untoasted", "untold", "untouched", "untracked", "untrained", + "untreated", "untried", "untrimmed", "untrue", "untruth", "unturned", "untwist", "untying", "unusable", "unused", "unusual", "unvalued", "unvaried", "unvarying", "unveiled", + "unveiling", "unvented", "unviable", "unvisited", "unvocal", "unwanted", "unwarlike", "unwary", "unwashed", "unwatched", "unweave", "unwed", "unwelcome", "unwell", "unwieldy", + "unwilling", "unwind", "unwired", "unwitting", "unwomanly", "unworldly", "unworn", "unworried", "unworthy", "unwound", "unwoven", "unwrapped", "unwritten", "unzip", "upbeat", + "upchuck", "upcoming", "upcountry", "update", "upfront", "upgrade", "upheaval", "upheld", "uphill", "uphold", "uplifted", "uplifting", "upload", "upon", "upper", + "upright", "uprising", "upriver", "uproar", "uproot", "upscale", "upside", "upstage", "upstairs", "upstart", "upstate", "upstream", "upstroke", "upswing", "uptake", + "uptight", "uptown", "upturned", "upward", "upwind", "uranium", "urban", "urchin", "urethane", "urgency", "urgent", "urging", "urologist", "urology", "usable", + "usage", "useable", "used", "uselessly", "user", "usher", "usual", "utensil", "utility", "utilize", "utmost", "utopia", "utter", "vacancy", "vacant", + "vacate", "vacation", "vagabond", "vagrancy", "vagrantly", "vaguely", "vagueness", "valiant", "valid", "valium", "valley", "valuables", "value", "vanilla", "vanish", + "vanity", "vanquish", "vantage", "vaporizer", "variable", "variably", "varied", "variety", "various", "varmint", "varnish", "varsity", "varying", "vascular", "vaseline", + "vastly", "vastness", "veal", "vegan", "veggie", "vehicular", "velcro", "velocity", "velvet", "vendetta", "vending", "vendor", "veneering", "vengeful", "venomous", + "ventricle", "venture", "venue", "venus", "verbalize", "verbally", "verbose", "verdict", "verify", "verse", "version", "versus", "vertebrae", "vertical", "vertigo", + "very", "vessel", "vest", "veteran", "veto", "vexingly", "viability", "viable", "vibes", "vice", "vicinity", "victory", "video", "viewable", "viewer", + "viewing", "viewless", "viewpoint", "vigorous", "village", "villain", "vindicate", "vineyard", "vintage", "violate", "violation", "violator", "violet", "violin", "viper", + "viral", "virtual", "virtuous", "virus", "visa", "viscosity", "viscous", "viselike", "visible", "visibly", "vision", "visiting", "visitor", "visor", "vista", + "vitality", "vitalize", "vitally", "vitamins", "vivacious", "vividly", "vividness", "vixen", "vocalist", "vocalize", "vocally", "vocation", "voice", "voicing", "void", + "volatile", "volley", "voltage", "volumes", "voter", "voting", "voucher", "vowed", "vowel", "voyage", "wackiness", "wad", "wafer", "waffle", "waged", + "wager", "wages", "waggle", "wagon", "wake", "waking", "walk", "walmart", "walnut", "walrus", "waltz", "wand", "wannabe", "wanted", "wanting", + "wasabi", "washable", "washbasin", "washboard", "washbowl", "washcloth", "washday", "washed", "washer", "washhouse", "washing", "washout", "washroom", "washstand", "washtub", + "wasp", "wasting", "watch", "water", "waviness", "waving", "wavy", "whacking", "whacky", "wham", "wharf", "wheat", "whenever", "whiff", "whimsical", + "whinny", "whiny", "whisking", "whoever", "whole", "whomever", "whoopee", "whooping", "whoops", "why", "wick", "widely", "widen", "widget", "widow", + "width", "wieldable", "wielder", "wife", "wifi", "wikipedia", "wildcard", "wildcat", "wilder", "wildfire", "wildfowl", "wildland", "wildlife", "wildly", "wildness", + "willed", "willfully", "willing", "willow", "willpower", "wilt", "wimp", "wince", "wincing", "wind", "wing", "winking", "winner", "winnings", "winter", + "wipe", "wired", "wireless", "wiring", "wiry", "wisdom", "wise", "wish", "wisplike", "wispy", "wistful", "wizard", "wobble", "wobbling", "wobbly", + "wok", "wolf", "wolverine", "womanhood", "womankind", "womanless", "womanlike", "womanly", "womb", "woof", "wooing", "wool", "woozy", "word", "work", + "worried", "worrier", "worrisome", "worry", "worsening", "worshiper", "worst", "wound", "woven", "wow", "wrangle", "wrath", "wreath", "wreckage", "wrecker", + "wrecking", "wrench", "wriggle", "wriggly", "wrinkle", "wrinkly", "wrist", "writing", "written", "wrongdoer", "wronged", "wrongful", "wrongly", "wrongness", "wrought", + "xbox", "xerox", "yahoo", "yam", "yanking", "yapping", "yard", "yarn", "yeah", "yearbook", "yearling", "yearly", "yearning", "yeast", "yelling", + "yelp", "yen", "yesterday", "yiddish", "yield", "yin", "yippee", "yo-yo", "yodel", "yoga", "yogurt", "yonder", "yoyo", "yummy", "zap", + "zealous", "zebra", "zen", "zeppelin", "zero", "zestfully", "zesty", "zigzagged", "zipfile", "zipping", "zippy", "zips", "zit", "zodiac", "zombie", + "zone", "zoning", "zookeeper", "zoologist", "zoology", "zoom", "zucchini", "zulu", "zumba", +} + +// RandomWord returns a random word from the word list +func RandomWord() string { + return wordList[rand.Intn(len(wordList))] +} diff --git a/release/internal/imagescanner/scanner.go b/release/internal/imagescanner/scanner.go new file mode 100644 index 00000000000..d3d164cf1e3 --- /dev/null +++ b/release/internal/imagescanner/scanner.go @@ -0,0 +1,157 @@ +package imagescanner + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "os" + "path/filepath" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/utils" +) + +const ( + scanResultFileName = "image-scan-result.json" +) + +// Config is the configuration for the image scanner. +type Config struct { + // APIURL is the URL for the Image Scan Service API + APIURL string `envconfig:"IMAGE_SCANNER_API"` + + // Token is the token for the Image Scan Service API + Token string `envconfig:"IMAGE_SCANNING_TOKEN"` + + // Scanner is the name of the scanner to use + Scanner string `envconfig:"IMAGE_SCANNER_SELECT" default:"all"` +} + +// Scanner is an image scanner. +type Scanner struct { + config Config +} + +// NewScanner creates a new image scanner. +func New(cfg Config) *Scanner { + return &Scanner{ + config: cfg, + } +} + +// Scan sends a request to the image scanner to scan the given images. +// The stream is the stream of the release. +// The release flag indicates if the images are for a release which run image and code scans. +// The outputDir is the directory to write the scan result to. If outputDir is empty, the scan result is not written to a file. +func (i *Scanner) Scan(images []string, stream string, release bool, outputDir string) error { + var bucketPath, scanType string + if release { + scanType = "release" + bucketPath = fmt.Sprintf("release/%s", stream) + } else { + scanType = "image" + bucketPath = fmt.Sprintf("hashrelease/%s", stream) + } + payload := map[string]interface{}{ + "images": images, + "bucket_path": bucketPath, + } + marshalled, err := json.Marshal(payload) + if err != nil { + logrus.WithError(err).Error("Failed to marshal payload for image scanner") + return err + } + req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/iss/scan", i.config.APIURL), bytes.NewReader(marshalled)) + if err != nil { + logrus.WithError(err).Error("Failed to create request for image scanner") + return err + } + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", i.config.Token)) + req.Header.Set("Content-Type", "application/json") + query := req.URL.Query() + query.Add("scan_type", scanType) + query.Add("scanner_select", i.config.Scanner) + query.Add("project_name", utils.ProductCode) + query.Add("project_version", stream) + req.URL.RawQuery = query.Encode() + logrus.WithFields(logrus.Fields{ + "images": images, + "bucket_path": bucketPath, + "scan_type": scanType, + "scanner": i.config.Scanner, + "version": stream, + }).Debug("Sending image scan request") + resp, err := http.DefaultClient.Do(req) + if err != nil { + logrus.WithError(err).Error("Failed to send request to image scanner") + return err + } + if outputDir != "" { + if err := writeScanResultToFile(resp, outputDir); err != nil { + logrus.WithError(err).Error("Failed to write image scan result to file") + return err + } + } + switch resp.StatusCode { + case http.StatusOK: + logrus.Info("Image scan request sent successfully") + return nil + case http.StatusLocked: + logrus.WithField("status", resp.StatusCode).Error("Image scan service is currently processing another request") + return fmt.Errorf("image scan service is currently processing another request") + default: + if resp.StatusCode >= 500 { + logrus.WithField("status", resp.StatusCode).Error("Image scan service is currently unavailable") + return fmt.Errorf("image scan service is currently unavailable") + } + logrus.WithField("status", resp.StatusCode).Error("Failed to send request to image scanner") + return fmt.Errorf("failed to send request to image scanner") + } +} + +// writeScanResultToFile writes the image scan result to a file. +func writeScanResultToFile(resp *http.Response, outputDir string) error { + defer resp.Body.Close() + outputFilePath := filepath.Join(outputDir, scanResultFileName) + if _, err := os.Stat(outputFilePath); err == nil { + logrus.WithField("file", outputFilePath).Error("Image scan result file already exists") + return fmt.Errorf("image scan result file already exists") + } + file, err := os.Create(outputFilePath) + if err != nil { + logrus.WithError(err).Error("Failed to create image scan result file") + return err + } + defer file.Close() + if _, err := file.ReadFrom(resp.Body); err != nil { + logrus.WithError(err).Error("Failed to write image scan result to file") + return err + } + logrus.WithField("file", outputFilePath).Info("Image scan result written to file") + return nil +} + +// RetrieveResultURL retrieves the URL to the image scan result from the scan result file. +func RetrieveResultURL(outputDir string) string { + outputFilePath := filepath.Join(outputDir, scanResultFileName) + if _, err := os.Stat(outputFilePath); os.IsNotExist(err) { + logrus.WithError(err).Error("Image scan result file does not exist") + return "" + } + var result map[string]interface{} + resultData, err := os.ReadFile(outputFilePath) + if err != nil { + logrus.WithError(err).Error("Failed to read image scan result file") + return "" + } + if err := json.Unmarshal(resultData, &result); err != nil { + logrus.WithError(err).Error("Failed to unmarshal image scan result") + return "" + } + if link, ok := result["results_link"].(string); ok { + return link + } + return "" +} diff --git a/release/internal/operator/git.go b/release/internal/operator/git.go new file mode 100644 index 00000000000..410bf894350 --- /dev/null +++ b/release/internal/operator/git.go @@ -0,0 +1,37 @@ +package operator + +import ( + "os" + "path/filepath" + + "github.com/projectcalico/calico/release/internal/command" + "github.com/projectcalico/calico/release/internal/utils" +) + +// Clone clones the operator repo into a path from the repoRootDir. +func Clone(cfg Config) error { + targetDir := cfg.Dir + clonePath := filepath.Dir(targetDir) + if err := os.MkdirAll(clonePath, utils.DirPerms); err != nil { + return err + } + if _, err := os.Stat(targetDir); !os.IsNotExist(err) { + _, err := command.GitInDir(targetDir, "checkout", cfg.Branch) + if err == nil { + _, err = command.GitInDir(targetDir, "pull") + return err + } + } + _, err := command.GitInDir(clonePath, "clone", cfg.Repo, "--branch", cfg.Branch) + return err +} + +// GitVersion returns the git version of the operator repo. +func GitVersion(operatorDir string) (string, error) { + return command.GitVersion(operatorDir, false) +} + +// GitBranch returns the git branch of the operator repo. +func GitBranch(operatorDir string) (string, error) { + return command.GitInDir(operatorDir, "rev-parse", "--abbrev-ref", "HEAD") +} diff --git a/release/internal/operator/operator.go b/release/internal/operator/operator.go new file mode 100644 index 00000000000..f603145edd7 --- /dev/null +++ b/release/internal/operator/operator.go @@ -0,0 +1,62 @@ +package operator + +import ( + "fmt" + "os" + "strings" + + "github.com/projectcalico/calico/release/internal/command" +) + +type Config struct { + // Repo is the repository for the operator + Repo string `envconfig:"OPERATOR_REPO" default:"git@github.com:tigera/operator.git"` + + // Branch is the repository for the operator + Branch string `envconfig:"OPERATOR_BRANCH" default:"master"` + + // Dir is the directory to clone the operator repository + Dir string `envconfig:"OPERATOR_DIR"` + + // Image is the image for Tigera operator + Image string `envconfig:"OPERATOR_IMAGE" default:"tigera/operator"` + + // Registry is the registry for Tigera operator + Registry string `envconfig:"OPERATOR_REGISTRY" default:"quay.io"` +} + +func (c Config) String() string { + return fmt.Sprintf("Repo: %s, Branch: %s, Image: %s, Registry: %s", c.Repo, c.Branch, c.Image, c.Registry) +} + +// GenVersions generates the versions for operator. +func GenVersions(componentsVersionPath, dir string) error { + env := os.Environ() + env = append(env, fmt.Sprintf("OS_VERSIONS=%s", componentsVersionPath)) + env = append(env, fmt.Sprintf("COMMON_VERSIONS=%s", componentsVersionPath)) + if _, err := command.MakeInDir(dir, []string{"gen-versions"}, env); err != nil { + return err + } + return nil +} + +// ImageAll build all the images for operator . +func ImageAll(archs []string, version, operatorDir string) error { + env := os.Environ() + env = append(env, fmt.Sprintf("ARCHES=%s", strings.Join(archs, " "))) + env = append(env, fmt.Sprintf("VERSION=%s", version)) + if _, err := command.MakeInDir(operatorDir, []string{"image-all"}, env); err != nil { + return err + } + return nil +} + +// InitImage build the init image for operator. +func InitImage(version, operatorDir string) error { + env := os.Environ() + env = append(env, fmt.Sprintf("VERSION=%s", version)) + if _, err := command.MakeInDir(operatorDir, []string{"image-init"}, env); err != nil { + return err + } + return nil +} diff --git a/release/internal/outputs/releasenotes.go b/release/internal/outputs/releasenotes.go new file mode 100644 index 00000000000..10f9e3b7dc9 --- /dev/null +++ b/release/internal/outputs/releasenotes.go @@ -0,0 +1,226 @@ +package outputs + +import ( + "context" + _ "embed" + "fmt" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + "text/template" + "time" + + "github.com/google/go-github/v53/github" + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/utils" + "github.com/projectcalico/calico/release/internal/version" +) + +const ( + releaseNoteRequiredLabel = "release-note-required" + closedState = issueState("closed") + openState = issueState("open") +) + +var ( + //go:embed templates/release-note.md.gotmpl + releaseNoteTemplate string + repos = []string{"calico", "bird"} +) + +type issueState string + +// ReleaseNoteIssueData represents the data for an release note issue +type ReleaseNoteIssueData struct { + ID int + Note string + Repo string + URL string + Author string +} + +// ReleaseNoteData represents the data for release notes +type ReleaseNoteData struct { + Date string + BugFixes []*ReleaseNoteIssueData + OtherChanges []*ReleaseNoteIssueData +} + +// milestoneNumber returns the milestone number for a given milestone +func milestoneNumber(client *github.Client, owner, repo, milestone string, opts *github.MilestoneListOptions) (int, error) { + for { + milestones, resp, err := client.Issues.ListMilestones(context.Background(), owner, repo, opts) + if err != nil { + return -1, err + } + for _, m := range milestones { + if m.GetTitle() == milestone { + return m.GetNumber(), nil + } + } + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + return -1, fmt.Errorf("milestone not found") +} + +// prIssuesByRepo returns all the PR issues for a given repo +func prIssuesByRepo(client *github.Client, owner, repo string, opts *github.IssueListByRepoOptions) ([]*github.Issue, error) { + prIssues := []*github.Issue{} + for { + issues, resp, err := client.Issues.ListByRepo(context.Background(), owner, repo, opts) + if err != nil { + return nil, err + } + for _, issue := range issues { + if issue.IsPullRequest() { + prIssues = append(prIssues, issue) + } + } + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + return prIssues, nil +} + +// extractReleaseNoteFromIssue extracts release notes from an issue. +// It looks for the release note block in the issue body and returns the content +// between the start and end markers. +func extractReleaseNoteFromIssue(issue *github.Issue) ([]string, error) { + body := issue.GetBody() + pattern := "```release-note(.*?)```" + re := regexp.MustCompile(pattern) + matches := re.FindAllStringSubmatch(body, -1) + if len(matches) == 0 { + return []string{issue.GetTitle()}, fmt.Errorf("no release notes found") + } + var notes []string + for _, match := range matches { + if len(match) > 1 { + notes = append(notes, match[1]) + } + } + return notes, nil +} + +// extractReleaseNote extracts release notes from a list of issues +func extractReleaseNote(repo string, issues []*github.Issue) ([]*ReleaseNoteIssueData, error) { + issueDataList := []*ReleaseNoteIssueData{} + for _, issue := range issues { + notes, err := extractReleaseNoteFromIssue(issue) + if err != nil && len(notes) == 0 { + logrus.WithError(err).Errorf("Failed to extract release notes for issue %d", issue.GetNumber()) + return nil, err + } + for _, note := range notes { + note = strings.TrimSpace(note) + if note == "TBD" { + logrus.WithFields(logrus.Fields{ + "url": issue.GetHTMLURL(), + "author": issue.GetUser().GetLogin(), + }).Warnf("Release note is TBD, please update the issue") + } + issueData := &ReleaseNoteIssueData{ + ID: issue.GetNumber(), + Note: note, + Repo: repo, + URL: issue.GetHTMLURL(), + Author: issue.GetUser().GetLogin(), + } + issueDataList = append(issueDataList, issueData) + } + } + return issueDataList, nil +} + +// outputReleaseNotes outputs the release notes to a file +func outputReleaseNotes(issueDataList []*ReleaseNoteIssueData, outputFilePath string) error { + dir := filepath.Dir(outputFilePath) + if err := os.MkdirAll(dir, utils.DirPerms); err != nil { + logrus.WithError(err).Errorf("Failed to create release notes folder %s", dir) + return err + } + logrus.WithField("template", releaseNoteTemplate).Info("Parsing release note template") + tmpl, err := template.New("release-note").Parse(releaseNoteTemplate) + if err != nil { + logrus.WithError(err).Error("Failed to parse release note template") + return err + } + logrus.Info("Generating release notes") + date := time.Now().Format("02 Jan 2006") + data := &ReleaseNoteData{ + Date: date, + OtherChanges: issueDataList, + } + releaseNotedFile, err := os.Create(outputFilePath) + if err != nil { + logrus.WithError(err).Error("Failed to create release notes file") + return err + } + defer releaseNotedFile.Close() + if err := tmpl.Execute(releaseNotedFile, data); err != nil { + logrus.WithError(err).Error("Failed to execute release note template") + return err + } + return nil +} + +// ReleaseNotes generates release notes for a milestone +// and outputs it to a file in /release-notes/-release-notes.md +func ReleaseNotes(owner, githubToken, repoRootDir, outputDir string, ver version.Version) (string, error) { + if githubToken == "" { + return "", fmt.Errorf("github token not set, set GITHUB_TOKEN environment variable") + } + if outputDir == "" { + logrus.Warn("No directory is set, using current directory") + outputDir = "." + } + + milestone := ver.Milestone() + githubClient := github.NewTokenClient(context.Background(), githubToken) + releaseNoteDataList := []*ReleaseNoteIssueData{} + opts := &github.MilestoneListOptions{ + State: string(openState), + } + for _, repo := range repos { + milestoneNumber, error := milestoneNumber(githubClient, owner, repo, milestone, opts) + if error != nil { + logrus.WithError(error).Warnf("Failed to retrieve milestone for %s", repo) + continue + } + opts := &github.IssueListByRepoOptions{ + Milestone: strconv.Itoa(milestoneNumber), + State: string(closedState), + Labels: []string{releaseNoteRequiredLabel}, + } + logrus.WithField("repo", repo).Debug("Getting issues") + prIssues, err := prIssuesByRepo(githubClient, owner, repo, opts) + if err != nil { + logrus.WithError(err).Errorf("Failed to get issues for %s", repo) + return "", err + } + relNoteDataList, err := extractReleaseNote(repo, prIssues) + if err != nil { + logrus.WithError(err).Error("Failed to extract release notes") + return "", err + } + releaseNoteDataList = append(releaseNoteDataList, relNoteDataList...) + } + if len(releaseNoteDataList) == 0 { + logrus.WithField("milestone", milestone).Error("No issues found for milestone") + return "", fmt.Errorf("no issues found for milestone %s", milestone) + } + releaseNoteFilePath := filepath.Join(outputDir, fmt.Sprintf("%s-release-notes.md", ver.FormattedString())) + if err := outputReleaseNotes(releaseNoteDataList, releaseNoteFilePath); err != nil { + logrus.WithError(err).Error("Failed to output release notes") + return "", err + } + return releaseNoteFilePath, nil +} diff --git a/release/internal/outputs/templates/release-note.md.gotmpl b/release/internal/outputs/templates/release-note.md.gotmpl new file mode 100644 index 00000000000..ecfb126243e --- /dev/null +++ b/release/internal/outputs/templates/release-note.md.gotmpl @@ -0,0 +1,18 @@ +{{.Date}} + +#### Headline feature 1 + +#### Headline feature 2 + +#### Bug fixes +{{if .BugFixes -}} +{{range .BugFixes}} +- {{.Note}} [{{.Repo}} {{.ID}}]({{.URL}}) (@{{.Author}}) +{{- end}} +{{- end}} +#### Other changes +{{if .OtherChanges -}} +{{range .OtherChanges}} +- {{.Note}} [{{.Repo}} {{.ID}}]({{.URL}}) (@{{.Author}}) +{{- end}} +{{- end}} diff --git a/release/internal/registry/auth.go b/release/internal/registry/auth.go new file mode 100644 index 00000000000..37b2870d04e --- /dev/null +++ b/release/internal/registry/auth.go @@ -0,0 +1,121 @@ +package registry + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "strings" + + "github.com/docker/docker/api/types/registry" + "github.com/sirupsen/logrus" +) + +type DockerConfig struct { + Auths map[string]registry.AuthConfig `json:"auths"` +} + +// readDockerConfig reads the docker config file. +func readDockerConfig() (DockerConfig, error) { + dockerConfigPath := filepath.Join(os.Getenv("HOME"), ".docker", "config.json") + file, err := os.Open(dockerConfigPath) + if err != nil { + logrus.WithError(err).Error("failed to open docker config file") + return DockerConfig{}, err + } + defer file.Close() + data, err := io.ReadAll(file) + if err != nil { + logrus.WithError(err).Error("failed to read docker config file") + return DockerConfig{}, err + } + var dockerConfig DockerConfig + if err := json.Unmarshal(data, &dockerConfig); err != nil { + logrus.WithError(err).Error("failed to unmarshal docker config") + return DockerConfig{}, err + } + return dockerConfig, nil +} + +// getAuthFromDockerConfig retrieves the auth from the docker config. +func getAuthFromDockerConfig(registryURL string) (registry.AuthConfig, error) { + dockerConfig, err := readDockerConfig() + if err != nil { + return registry.AuthConfig{}, err + } + for reg, auth := range dockerConfig.Auths { + if strings.Contains(reg, registryURL) { + decoded, err := base64.URLEncoding.DecodeString(auth.Auth) + if err != nil { + return registry.AuthConfig{}, fmt.Errorf("failed to decode auth: %w", err) + } + parts := strings.Split(string(decoded), ":") + return registry.AuthConfig{ + Username: parts[0], + Password: parts[1], + ServerAddress: registryURL, + }, nil + } + } + return registry.AuthConfig{}, fmt.Errorf("no auth found for %s", registryURL) +} + +// getBearerToken retrieves a bearer token to use for the image. +func getBearerToken(registry Registry, scope string) (string, error) { + return getBearerTokenWithAuth("", registry, scope) +} + +// getBearerTokenWithDefaultAuth retrieves a bearer token to use for the image with default authentication. +// Default authentication is the authentication from the docker config. +func getBearerTokenWithDefaultAuth(registry Registry, scope string) (string, error) { + auth, err := getAuthFromDockerConfig(registry.URL()) + if err != nil { + return "", fmt.Errorf("failed to get auth from docker config: %w", err) + } + return getBearerTokenWithAuth(fmt.Sprintf("%s:%s", auth.Username, auth.Password), registry, scope) +} + +// getBearerTokenWithAuth retrieves a bearer token to use for the image with given authentication. +func getBearerTokenWithAuth(auth string, registry Registry, scope string) (string, error) { + tokenURL := registry.TokenURL(scope) + logrus.WithField("tokenURL", tokenURL).Debug("Getting bearer token") + req, err := http.NewRequest(http.MethodGet, tokenURL, nil) + if err != nil { + return "", err + } + if auth != "" { + parts := strings.Split(auth, ":") + req.SetBasicAuth(parts[0], parts[1]) + } + res, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to get bearer token: %s", res.Status) + } + resp := map[string]interface{}{} + if err := json.NewDecoder(res.Body).Decode(&resp); err != nil { + return "", err + } + return resp["token"].(string), nil +} + +// registryAuthStr returns the base64 encoded registry auth string. +func registryAuthStr(registry Registry) (string, error) { + registryAuthConfig, err := getAuthFromDockerConfig(registry.URL()) + if err != nil { + logrus.WithError(err).Error("failed to get auth config") + return "", err + } + registryAuth, err := json.Marshal(registryAuthConfig) + if err != nil { + logrus.WithError(err).Error("failed to marshal auth config") + return "", err + } + return base64.URLEncoding.EncodeToString(registryAuth), nil +} diff --git a/release/internal/registry/docker.go b/release/internal/registry/docker.go new file mode 100644 index 00000000000..3c8ab7b416e --- /dev/null +++ b/release/internal/registry/docker.go @@ -0,0 +1,23 @@ +package registry + +import ( + "fmt" +) + +// Docker represents the Docker registry +type Docker struct{} + +// URL returns the URL for the Docker registry +func (d *Docker) URL() string { + return "docker.io" +} + +// TokenURL returns the token URL for the Docker registry +func (d *Docker) TokenURL(scope string) string { + return fmt.Sprintf("https://auth.%s/token?service=registry.docker.io&scope=%s", d.URL(), scope) +} + +// ManifestURL returns the manifest URL for the Docker registry +func (d *Docker) ManifestURL(img ImageRef) string { + return fmt.Sprintf("https://registry-1.%s/v2/%s/manifests/%s", d.URL(), img.Repository(), img.Tag()) +} diff --git a/release/internal/registry/dockerrunner.go b/release/internal/registry/dockerrunner.go new file mode 100644 index 00000000000..c938656088c --- /dev/null +++ b/release/internal/registry/dockerrunner.go @@ -0,0 +1,262 @@ +package registry + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "os" + + "github.com/docker/distribution/manifest/manifestlist" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/client" + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/command" +) + +// TagsResponse is a struct for the response from the docker registry API for tags +type TagsResponse struct { + Name string `json:"name"` + Tags []string `json:"tags"` +} + +// DockerRunner is a struct for running docker commands +type DockerRunner struct { + dockerClient *client.Client +} + +// ManifestList represents a Docker Manifest List +type ManifestList struct { + SchemaVersion int `json:"schemaVersion"` + MediaType string `json:"mediaType"` + Manifests []manifestlist.ManifestDescriptor `json:"manifests"` +} + +// NewDockerRunner returns a new DockerRunner +func NewDockerRunner() (d *DockerRunner, err error) { + dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + logrus.WithError(err).Error("failed to create docker client") + return nil, err + } + return &DockerRunner{ + dockerClient: dockerClient, + }, nil +} + +// MustDockerRunner returns a new DockerRunner or exits the program +func MustDockerRunner() *DockerRunner { + d, err := NewDockerRunner() + if err != nil { + logrus.WithError(err).Fatal("failed to create docker runner") + } + return d +} + +// PullImage pulls the image if it does not exist +func (d *DockerRunner) PullImage(img string) error { + logrus.WithField("image", img).Debug("Checking if image exists") + imageSummary, err := d.dockerClient.ImageList(context.Background(), image.ListOptions{ + Filters: filters.NewArgs(filters.Arg("reference", img)), + }) + if err != nil { + logrus.WithError(err).Error("failed to list images") + return err + } + if len(imageSummary) == 0 { + logrus.WithField("image", img).Debug("Image does not exist, pulling...") + reader, err := d.dockerClient.ImagePull(context.Background(), img, image.PullOptions{}) + if err != nil { + logrus.WithError(err).Error("failed to pull image") + return err + } + defer reader.Close() + if _, err := io.Copy(os.Stdout, reader); err != nil { + logrus.WithError(err).Error("failed to copy image pull output") + return err + } + } + return nil +} + +// TagImage tags the image with the new tag +func (d *DockerRunner) TagImage(currentTag, newTag string) error { + logrus.WithFields(logrus.Fields{ + "currentTag": currentTag, + "newTag": newTag, + }).Debug("Tagging image") + if err := d.dockerClient.ImageTag(context.Background(), currentTag, newTag); err != nil { + logrus.WithError(err).Error("failed to tag image") + return err + } + return nil +} + +type errorMessage struct { + Error string +} + +// PushImage pushes the image to the registry +func (d *DockerRunner) PushImage(img string) error { + logrus.WithField("image", img).Debug("Pushing image") + registryAuth, err := registryAuthStr(ParseImage(img).Registry()) + if err != nil { + logrus.WithError(err).Error("failed to get registry auth") + return err + } + reader, err := d.dockerClient.ImagePush(context.Background(), img, image.PushOptions{ + RegistryAuth: registryAuth, + }) + if err != nil { + logrus.WithField("image", img).WithError(err).Error("failed to push image") + return err + } + defer reader.Close() + var errorMessage errorMessage + buffIOReader := bufio.NewReader(reader) + for { + stream, err := buffIOReader.ReadBytes('\n') + if err == io.EOF { + break + } + if err := json.Unmarshal(stream, &errorMessage); err != nil { + logrus.WithError(err).Error("failed to unmarshal push response") + return err + } + if errorMessage.Error != "" { + logrus.WithField("error", errorMessage).Error("failed to push image") + return fmt.Errorf("%s", errorMessage.Error) + } + } + logrus.WithField("image", img).Debug("Image pushed") + return nil +} + +// RemoveImage removes the image if it exists +func (d *DockerRunner) RemoveImage(img string) error { + logrus.WithField("image", img).Debug("Checking if image exists") + images, err := d.dockerClient.ImageList(context.Background(), image.ListOptions{ + Filters: filters.NewArgs(filters.Arg("reference", img)), + }) + if err != nil { + logrus.WithError(err).Error("failed to list images") + return err + } + if len(images) == 0 { + logrus.Debug(img, " image does not exist") + return nil + } + + for _, img := range images { + logrus.WithField("image", img.ID).Debug("Removing image") + _, err := d.dockerClient.ImageRemove(context.Background(), img.ID, image.RemoveOptions{ + Force: true, + PruneChildren: true, + }) + if err != nil { + logrus.WithField("image", img.ID).WithError(err).Error("failed to remove image") + return err + } + logrus.WithField("image", img.ID).Debug("Image removed") + } + return nil +} + +// ManifestPush pushes the manifest list to the registry. +// +// Since "docker manifest create/push" is considered experimental, it is not supported in the docker client library. +// As a workaround, we can use the docker command to create and push the manifest list. +func (d *DockerRunner) ManifestPush(manifestListName string, images []string) error { + createArgs := []string{"manifest", "create", "--amend", manifestListName} + createArgs = append(createArgs, images...) + if _, err := command.Run("docker", createArgs); err != nil { + logrus.WithError(err).Error("failed to create manifest list") + return err + } + if _, err := command.Run("docker", []string{"manifest", "push", manifestListName}); err != nil { + logrus.WithError(err).Error("failed to push manifest list") + return err + } + return nil +} + +// RunContainer runs a container with the given config and host config +func (d *DockerRunner) RunContainer(containerConfig *container.Config, hostConfig *container.HostConfig) (container.CreateResponse, error) { + logrus.WithField("image", containerConfig.Image).Debug("Creating container") + response, err := d.dockerClient.ContainerCreate(context.Background(), containerConfig, hostConfig, nil, nil, "") + if err != nil { + logrus.WithError(err).Error("failed to create container") + return container.CreateResponse{}, err + } + + logrus.WithField("containerID", response.ID).Debug("Starting container ", response.ID) + if err := d.dockerClient.ContainerStart(context.Background(), response.ID, container.StartOptions{}); err != nil { + logrus.WithField("containerID", response.ID).WithError(err).Error("failed to start container") + return container.CreateResponse{}, err + } + return response, nil +} + +// ExecInContainer executes a command in the container +func (d *DockerRunner) ExecInContainer(containerID string, cmd ...string) (container.ExecInspect, error) { + logrus.WithFields(logrus.Fields{ + "containerID": containerID, + "cmd": cmd, + }).Debug("Creating exec instance") + exec, err := d.dockerClient.ContainerExecCreate(context.Background(), containerID, container.ExecOptions{ + AttachStdout: true, + AttachStderr: true, + Cmd: cmd, + }) + if err != nil { + logrus.WithError(err).Error("failed to create exec instance") + return container.ExecInspect{}, err + } + + logrus.WithFields(logrus.Fields{ + "containerID": containerID, + "execID": exec.ID, + }).Debug("Attach to the exec instance") + resp, err := d.dockerClient.ContainerExecAttach(context.Background(), exec.ID, container.ExecAttachOptions{}) + if err != nil { + logrus.WithError(err).Error("failed to start exec instance") + } + defer resp.Close() + + output, err := io.ReadAll(resp.Reader) + if err != nil { + logrus.WithError(err).Error("failed to read exec output") + return container.ExecInspect{}, err + } + + logrus.WithField("cmd", cmd).Infof("printing output...\n%s\n...end of output", string(output)) + + inspect, err := d.dockerClient.ContainerExecInspect(context.Background(), exec.ID) + if err != nil { + logrus.WithError(err).Error("failed to inspect exec instance") + return container.ExecInspect{}, err + } + return inspect, nil +} + +// StopContainer stops the container +func (d *DockerRunner) StopContainer(containerID string) error { + if err := d.dockerClient.ContainerStop(context.Background(), containerID, container.StopOptions{}); err != nil { + logrus.WithError(err).Error("failed to stop container") + return err + } + return nil +} + +// RemoveContainer removes the container +func (d *DockerRunner) RemoveContainer(containerID string) error { + if err := d.dockerClient.ContainerRemove(context.Background(), containerID, container.RemoveOptions{}); err != nil { + logrus.WithError(err).Error("failed to remove container") + return err + } + return nil +} diff --git a/release/internal/registry/image.go b/release/internal/registry/image.go new file mode 100644 index 00000000000..db4d3e74a4b --- /dev/null +++ b/release/internal/registry/image.go @@ -0,0 +1,105 @@ +package registry + +import ( + "context" + "fmt" + "io" + "net/http" + + "github.com/docker/distribution/manifest/manifestlist" + "github.com/docker/distribution/reference" + "github.com/sirupsen/logrus" +) + +// ImageMap maps the image name to the repository. +var ImageMap = map[string]string{ + "typha": "calico/typha", + "calicoctl": "calico/ctl", + "flannel": "coreos/flannel", + "flexvol": "calico/pod2daemon-flexvol", + "key-cert-provisioner": "calico/key-cert-provisioner", + "csi-node-driver-registrar": "calico/node-driver-registrar", +} + +// privateImages is a list of images that require authentication. +var privateImages = []string{} + +// ImageRef represents a container image. +type ImageRef struct { + ref reference.Named +} + +// Repository returns the repository part of the image. +func (i ImageRef) Repository() string { + return reference.Path(i.ref) +} + +// Tag returns the tag part of the image. +func (i ImageRef) Tag() string { + return reference.TagNameOnly(i.ref).(reference.NamedTagged).Tag() +} + +func (i ImageRef) Registry() Registry { + domain := reference.Domain(i.ref) + return GetRegistry(domain) +} + +func (i ImageRef) RequiresAuth() bool { + for _, img := range privateImages { + if i.Repository() == img { + return true + } + } + return false +} + +func ParseImage(img string) ImageRef { + ref, err := reference.ParseNormalizedNamed(img) + if err != nil { + logrus.WithError(err).Fatal("Failed to parse image") + } + return ImageRef{ref} +} + +// ImageExists checks if an image exists in a registry. +func ImageExists(img ImageRef) (bool, error) { + registry := img.Registry() + scope := fmt.Sprintf("repository:%s:pull", img.Repository()) + var token string + var err error + if img.RequiresAuth() { + token, err = getBearerTokenWithDefaultAuth(registry, scope) + } else { + token, err = getBearerToken(registry, scope) + } + if err != nil { + return false, err + } + manifestURL := registry.ManifestURL(img) + logrus.WithFields(logrus.Fields{ + "image": img, + "manifestURL": manifestURL, + }).Debug("Checking if image exists") + req, err := http.NewRequest(http.MethodGet, manifestURL, nil) + if err != nil { + logrus.WithError(err).Error("Failed to create request") + return false, err + } + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) + // Docker Hub requires the "Accept" header to be set for manifest requests. + // While it is forgiving in most cases, windows images request will fail without it. + req.Header.Set("Accept", manifestlist.MediaTypeManifestList) + resp, err := http.DefaultClient.Do(req.WithContext(context.Background())) + if err != nil { + logrus.WithError(err).Error("Failed to get manifest") + return false, err + } + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + return true, nil + } else if resp.StatusCode == http.StatusNotFound { + body, _ := io.ReadAll(resp.Body) + return false, fmt.Errorf("unable to find image: %s", body) + } + return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode) +} diff --git a/release/internal/registry/quay.go b/release/internal/registry/quay.go new file mode 100644 index 00000000000..e6a61720709 --- /dev/null +++ b/release/internal/registry/quay.go @@ -0,0 +1,23 @@ +package registry + +import ( + "fmt" +) + +// Quay represents the Quay registry +type Quay struct{} + +// URL returns the URL for the Quay registry +func (q *Quay) URL() string { + return "quay.io" +} + +// TokenURL returns the token URL for the Quay registry +func (q *Quay) TokenURL(scope string) string { + return fmt.Sprintf("https://%s/v2/auth?service=quay.io&scope=%s", q.URL(), scope) +} + +// ManifestURL returns the manifest URL for the Quay registry +func (q *Quay) ManifestURL(img ImageRef) string { + return fmt.Sprintf("https://%s/v2/%s/manifests/%s", q.URL(), img.Repository(), img.Tag()) +} diff --git a/release/internal/registry/registry.go b/release/internal/registry/registry.go new file mode 100644 index 00000000000..0bab891aa6f --- /dev/null +++ b/release/internal/registry/registry.go @@ -0,0 +1,25 @@ +package registry + +const ( + QuayRegistry = "quay.io" + DockerRegistry = "docker.io" +) + +// Registry represents a container registry. +type Registry interface { + URL() string + TokenURL(scope string) string + ManifestURL(img ImageRef) string +} + +// GetRegistry returns a Registry based on the registry string. +func GetRegistry(registry string) Registry { + switch registry { + case QuayRegistry: + return &Quay{} + case DockerRegistry: + return &Docker{} + default: + return &Docker{} + } +} diff --git a/release/internal/slack/slack.go b/release/internal/slack/slack.go new file mode 100644 index 00000000000..65526d1350b --- /dev/null +++ b/release/internal/slack/slack.go @@ -0,0 +1,132 @@ +package slack + +import ( + "bytes" + _ "embed" + "fmt" + "text/template" + + "github.com/sirupsen/logrus" + "github.com/slack-go/slack" + + "github.com/projectcalico/calico/release/internal/hashrelease" +) + +var ( + //go:embed templates/success.json.gotmpl + successMessageTemplateData string + //go:embed templates/failure.json.gotmpl + failureMessageTemplateData string +) + +// Config is the configuration for the Slack client +type Config struct { + // Token is the token for the Slack API + Token string `envconfig:"SLACK_API_TOKEN"` + + // Channel is the channel to post messages + Channel string `envconfig:"SLACK_CHANNEL"` +} + +// MessageData is the data to be rendered in the message +type MessageData struct { + // ReleaseName is the name of the release + ReleaseName string + + // Product is the name of the product + Product string + + // Stream is the stream of the release + Stream string + + // Version is the version of the release + Version string + + // OperatorVersion is the version of the operator + OperatorVersion string + + // DocsURL is the URL for the release docs. + // This is only used for success messages + DocsURL string + + // CIURL is the URL for the CI job. + // This is required for failure messages + // and optional for success messages. + CIURL string + + // ImageScanResultURL is the URL for the results from the image scanner. + // This is only used for success messages + ImageScanResultURL string + + // FailedImages is the list of failed images. + // This is required for failure messages + FailedImages []hashrelease.Component +} + +// Message is a Slack message +type Message struct { + // Config is the configuration for the message + Config Config + + // Data is the data to be rendered in the message + Data MessageData +} + +// Create a new Slack client +func client(token string, debug bool) *slack.Client { + options := []slack.Option{} + if debug { + options = append(options, slack.OptionDebug(true)) + } + client := slack.New(token, options...) + return client +} + +// SendFailure sends a failure message to Slack +func (m *Message) SendFailure(debug bool) error { + if len(m.Data.FailedImages) == 0 { + return fmt.Errorf("no failed images to report") + } + if m.Data.CIURL == "" { + return fmt.Errorf("CI URL is required for failure messages") + } + client := client(m.Config.Token, debug) + return m.send(client, failureMessageTemplateData) +} + +// SendSuccess sends a success message to Slack +func (m *Message) SendSuccess(debug bool) error { + client := client(m.Config.Token, debug) + return m.send(client, successMessageTemplateData) +} + +// send sends the message to Slack +func (m *Message) send(client *slack.Client, messageTemplateData string) error { + message, err := m.renderMessage(messageTemplateData) + if err != nil { + return err + } + logrus.WithFields(logrus.Fields{ + "channel": m.Config.Channel, + "message": message, + }).Debug("Sending message to Slack") + _, _, err = client.PostMessage(m.Config.Channel, slack.MsgOptionBlocks(message...)) + return err +} + +// renderMessage renders the message from the template +func (m *Message) renderMessage(templateData string) ([]slack.Block, error) { + tmpl, err := template.New("message").Parse(templateData) + if err != nil { + return nil, err + } + var buf bytes.Buffer + if err := tmpl.Execute(&buf, m.Data); err != nil { + return nil, err + } + blocks := slack.Blocks{} + if err := blocks.UnmarshalJSON(buf.Bytes()); err != nil { + return nil, err + } + return blocks.BlockSet, nil +} diff --git a/release/internal/slack/templates/failure.json.gotmpl b/release/internal/slack/templates/failure.json.gotmpl new file mode 100644 index 00000000000..316829f336c --- /dev/null +++ b/release/internal/slack/templates/failure.json.gotmpl @@ -0,0 +1,85 @@ +[ + { + "type": "header", + "text": { + "type": "plain_text", + "text": ":warning: Failed to create {{.Product}} {{.Stream}} release" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*{{.ReleaseName}}*" + } + {{- if .CIURL}}, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": ":building_construction: Build Details", + "emoji": true + }, + "value": "ci_link", + "url": "{{.CIURL}}" + } + {{- end }} + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "{{.Version}}\nOperator {{.OperatorVersion}}" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "plain_text", + "text": "See the list of unavailable images and versions below :arrow_heading_down:", + "emoji": true + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Images*" + }, + { + "type": "mrkdwn", + "text": "*Version*" + } + {{- range $component := .FailedImages }}, + { + "type": "plain_text", + "text": "{{$component.Image}}" + }, + { + "type": "plain_text", + "text": "{{$component.Version}}" + } + {{- end }} + ] + } + {{- if not .CIURL }}, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "plain_text", + "text": "This release was not built by CI." + } + ] + } + {{- end }} +] diff --git a/release/internal/slack/templates/success.json.gotmpl b/release/internal/slack/templates/success.json.gotmpl new file mode 100644 index 00000000000..18df96604fe --- /dev/null +++ b/release/internal/slack/templates/success.json.gotmpl @@ -0,0 +1,99 @@ +[ + { + "type": "header", + "text": { + "type": "plain_text", + "text": ":loud_sound: New {{.Product}} {{.Stream}} release" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*<{{.DocsURL}}|{{.ReleaseName}}>*" + } + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Version:{{.Version}}\nOperator {{.OperatorVersion}}" + } + ] + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": ":book: Docs", + "emoji": true + }, + "value": "docs_link", + "url": "{{.DocsURL}}" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": ":page_with_curl: Manifests", + "emoji": true + }, + "value": "manifests_link", + "url": "{{.DocsURL}}/manifests" + } + {{- if .ImageScanResultURL }}, + { + "type": "button", + "text": { + "type": "plain_text", + "text": ":mag: Images Scan Result", + "emoji": true + }, + "value": "image_scan_link", + "url": "{{.ImageScanResultURL}}" + } + {{- end }} + {{- if .CIURL }}, + { + "type": "button", + "text": { + "type": "plain_text", + "text": ":building_construction: Build Details", + "emoji": true + }, + "value": "ci_link", + "url": "{{.CIURL}}" + } + {{- end }} + ] + } + {{- if not .ImageScanResultURL }}, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": ":warning: Image scan results are not available for this release." + } + ] + } + {{- end }} + {{- if not .CIURL }}, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "plain_text", + "text": "This release was not built by CI." + } + ] + } + {{- end }} +] diff --git a/release/internal/utils/config.go b/release/internal/utils/config.go new file mode 100644 index 00000000000..299993d1848 --- /dev/null +++ b/release/internal/utils/config.go @@ -0,0 +1,19 @@ +package utils + +import ( + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +const ( + // ProductName is the name of the product. + ProductName = "calico" + + // ProductCode is the code of the product. + ProductCode = "os" +) + +// DisplayProductName returns the product name in title case. +func DisplayProductName() string { + return cases.Title(language.English).String(ProductName) +} diff --git a/release/internal/utils/files.go b/release/internal/utils/files.go new file mode 100644 index 00000000000..a77dc780df7 --- /dev/null +++ b/release/internal/utils/files.go @@ -0,0 +1,46 @@ +package utils + +import ( + "fmt" + "os" + "path/filepath" +) + +const ( + // ReleaseFolderName is the name of the release tool in this repository. + ReleaseFolderName = "release" + + // DirPerms is the permissions for directories. + DirPerms os.FileMode = 0o755 +) + +// MoveFile moves a file from srcPattern to dstFile. +// srcPattern should match exactly one file. +func MoveFile(srcPattern, dstFile string) error { + files, err := filepath.Glob(srcPattern) + if err != nil { + return fmt.Errorf("failed to find files matching pattern %s: %s", srcPattern, err) + } + if len(files) != 1 { + return fmt.Errorf("expected to find exactly one file matching pattern %s, but found %d", srcPattern, len(files)) + } + srcFile := files[0] + if err := os.Rename(srcFile, dstFile); err != nil { + return fmt.Errorf("failed to move file %s to %s: %v", srcFile, dstFile, err) + } + return nil +} + +func CopyFile(src, dst string) error { + input, err := os.ReadFile(src) + if err != nil { + return err + } + + err = os.WriteFile(dst, input, 0o644) + if err != nil { + fmt.Println("Error creating", dst) + return err + } + return nil +} diff --git a/release/internal/utils/git.go b/release/internal/utils/git.go new file mode 100644 index 00000000000..3d6c7e8f8c4 --- /dev/null +++ b/release/internal/utils/git.go @@ -0,0 +1,40 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "strings" + + "github.com/projectcalico/calico/release/internal/command" +) + +const ( + // DefaultBranch is the default branch of the repository. + DefaultBranch = "master" +) + +// GitBranch returns the current git branch of the repository. +func GitBranch(dir string) (string, error) { + return command.GitInDir(dir, "rev-parse", "--abbrev-ref", "HEAD") +} + +// GitIsDirty returns true if the repository is dirty. +func GitIsDirty(dir string) (bool, error) { + version, err := command.GitVersion(dir, true) + if err != nil { + return false, err + } + return strings.HasSuffix(version, "-dirty"), nil +} diff --git a/release/internal/version/version.go b/release/internal/version/version.go new file mode 100644 index 00000000000..09a7c849f95 --- /dev/null +++ b/release/internal/version/version.go @@ -0,0 +1,167 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package version + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/command" + "github.com/projectcalico/calico/release/internal/utils" +) + +// Version represents a version, and contains methods for working with versions. +type Version string + +// New creates a new Version object from the given string. +func New(version string) Version { + if _, err := semver.NewVersion(strings.TrimPrefix(version, "v")); err != nil { + logrus.WithField("version", version).WithError(err).Fatal("Failed to parse version") + } + return Version(version) +} + +// String returns the string representation of the version. +func (v *Version) String() string { + ver, err := semver.NewVersion(strings.TrimPrefix(string(*v), "v")) + if err != nil { + return "" + } + return ver.String() +} + +// FormattedString returns the formatted string representation of the version. +func (v *Version) FormattedString() string { + return fmt.Sprintf("v%v", v.String()) +} + +// Milestone returns the GitHub milestone name which corresponds with this version. +func (v *Version) Milestone() string { + ver := semver.MustParse(string(*v)) + return fmt.Sprintf("%s v%d.%d.%d", utils.DisplayProductName(), ver.Major(), ver.Minor(), ver.Patch()) +} + +// Stream returns the "release stream" of the version, i.e., the major and minor version without the patch version. +func (v *Version) Stream() string { + ver := semver.MustParse(string(*v)) + return fmt.Sprintf("v%d.%d", ver.Major(), ver.Minor()) +} + +// ReleaseBranch returns the release branch which corresponds with this version. +func (v *Version) ReleaseBranch(releaseBranchPrefix string) string { + return fmt.Sprintf("%s-%s", releaseBranchPrefix, v.Stream()) +} + +// GitVersion returns the current git version of the repository as a Version object. +func GitVersion() Version { + // First, determine the git revision. + previousTag, err := command.GitVersion(".", true) + if err != nil { + logrus.WithError(err).Fatal("Failed to determine latest git version") + } + logrus.WithField("out", previousTag).Info("Current git describe") + return New(previousTag) +} + +// DetermineReleaseVersion uses historical clues to figure out the next semver +// release number to use for this release based on the current git revision. +// +// OSS Calico uses the following rules: +// - If the current git revision is a "vX.Y.Z-0.dev-N-gCOMMIT" tag, then the next release version is simply vX.Y.Z. +// - If the current git revision is a patch release (e.g., vX.Y.Z-N-gCOMMIT), then the next release version is vX.Y.Z+1. +func DetermineReleaseVersion(v Version, devTagSuffix string) (Version, error) { + gitVersion := v.FormattedString() + + if !strings.HasPrefix(devTagSuffix, "-") { + // The dev tag marker should start with a hyphen. + // For example in "v3.15.0-0.dev-1-g1234567", we want to split on the "-0.dev" part. + devTagSuffix = "-" + devTagSuffix + } + + // There are two types of tag that this might be - either it was a previous patch release, + // or it was a "vX.Y.Z-0.dev" tag produced when cutting the release branch. + if strings.Contains(gitVersion, devTagSuffix) { + // This is the first release from this branch - we can simply extract the version from + // the dev tag. + return New(strings.Split(gitVersion, devTagSuffix)[0]), nil + } else { + // This is a patch release - we need to parse the previous, and + // bump the patch version. + previousVersion := strings.Split(gitVersion, "-")[0] + logrus.WithField("previousVersion", previousVersion).Info("Previous version") + v, err := semver.NewVersion(strings.TrimPrefix(previousVersion, "v")) + if err != nil { + logrus.WithField("previousVersion", previousVersion).WithError(err).Error("Failed to parse git version as semver") + return "", fmt.Errorf("failed to parse git version as semver: %s", err) + } + newVersion := v.IncPatch() + return New(fmt.Sprintf("v%s", newVersion.String())), nil + } +} + +// DetermineOperatorVersion returns the operator version that will be used for this release. +// This is determined by looking at the tigera-operator.yaml manifest on this commit, as +// manifests are updated prior to cutting the release. +func DetermineOperatorVersion(repoRoot string) (Version, error) { + return versionFromManifest(repoRoot, "tigera-operator.yaml", "operator") +} + +// VersionsFromManifests returns the versions of the product and operator from manifests. +func VersionsFromManifests(repoRoot string) (Version, Version, error) { + productVersion, err := versionFromManifest(repoRoot, "ocp/02-tigera-operator.yaml", "ctl") + if err != nil { + return "", "", err + } + operatorVersion, err := versionFromManifest(repoRoot, "tigera-operator.yaml", "operator") + if err != nil { + return "", "", err + } + return productVersion, operatorVersion, nil +} + +// DeterminePublishStream returns the stream for a given branch and version. +// If the branch is the default branch i.e. master, the stream is master. +// Otherwise, the stream is the major and minor version of the version. +func DeterminePublishStream(branch string, version string) string { + if branch == utils.DefaultBranch { + return branch + } + ver := New(version) + return ver.Stream() +} + +// versionFromManifest returns the version of the image matching the given match string from the given manifest. +func versionFromManifest(repoRoot, manifest, imgMatch string) (Version, error) { + runner := &command.RealCommandRunner{} + args := []string{"-Po", `image:\K(.*)`, manifest} + out, err := runner.RunInDir(filepath.Join(repoRoot, "manifests"), "grep", args, nil) + if err != nil { + return "", fmt.Errorf("failed to grep for image in manifest %s: %s", manifest, err) + } + + imgs := strings.Split(out, "\n") + for _, i := range imgs { + if strings.Contains(i, imgMatch) { + splits := strings.SplitAfter(i, ":") + ver := splits[len(splits)-1] + return New(ver), nil + } + } + return "", fmt.Errorf("image for %s not found in manifest %s", imgMatch, manifest) +} diff --git a/release/internal/version/version_test.go b/release/internal/version/version_test.go new file mode 100644 index 00000000000..c87c504e9d3 --- /dev/null +++ b/release/internal/version/version_test.go @@ -0,0 +1,48 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package version_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/projectcalico/calico/release/internal/version" +) + +func TestDetermineReleaseVersion(t *testing.T) { + expectations := map[string]string{ + // Simple base case - increment the patch number if cutting from an existing tag. + "v3.20.0": "v3.20.1", + "v3.20.1": "v3.20.2", + "v3.22.0": "v3.22.1", + "v3.22.10": "v3.22.11", + "v3.0.0": "v3.0.1", + + // A dev tag leading up to a minor release should return the minor release number. + "v3.29.0-0.dev-424-gfd40f1838223": "v3.29.0", + "v3.22.0-0.dev": "v3.22.0", + + // Previous tag was a patch release, should increment the patch number. + "v3.15.0-12-gfd40f1838223": "v3.15.1", + "v3.15.1-15-gfd40f1838223": "v3.15.2", + } + + for current, next := range expectations { + actual, err := version.DetermineReleaseVersion(version.New(current), "0.dev") + require.NoError(t, err) + require.Equal(t, next, actual.FormattedString()) + } +} diff --git a/hack/release/packaging/.gitignore b/release/packaging/.gitignore similarity index 100% rename from hack/release/packaging/.gitignore rename to release/packaging/.gitignore diff --git a/hack/release/packaging/LICENSE b/release/packaging/LICENSE similarity index 100% rename from hack/release/packaging/LICENSE rename to release/packaging/LICENSE diff --git a/hack/release/packaging/Makefile b/release/packaging/Makefile similarity index 100% rename from hack/release/packaging/Makefile rename to release/packaging/Makefile diff --git a/hack/release/packaging/README.md b/release/packaging/README.md similarity index 100% rename from hack/release/packaging/README.md rename to release/packaging/README.md diff --git a/hack/release/packaging/docker-build-images/centos7-build.Dockerfile.amd64 b/release/packaging/docker-build-images/centos7-build.Dockerfile.amd64 similarity index 100% rename from hack/release/packaging/docker-build-images/centos7-build.Dockerfile.amd64 rename to release/packaging/docker-build-images/centos7-build.Dockerfile.amd64 diff --git a/hack/release/packaging/docker-build-images/centos7-build.Dockerfile.ppc64le b/release/packaging/docker-build-images/centos7-build.Dockerfile.ppc64le similarity index 100% rename from hack/release/packaging/docker-build-images/centos7-build.Dockerfile.ppc64le rename to release/packaging/docker-build-images/centos7-build.Dockerfile.ppc64le diff --git a/hack/release/packaging/docker-build-images/docker-bake.hcl b/release/packaging/docker-build-images/docker-bake.hcl similarity index 100% rename from hack/release/packaging/docker-build-images/docker-bake.hcl rename to release/packaging/docker-build-images/docker-bake.hcl diff --git a/hack/release/packaging/docker-build-images/install-centos-build-deps b/release/packaging/docker-build-images/install-centos-build-deps similarity index 100% rename from hack/release/packaging/docker-build-images/install-centos-build-deps rename to release/packaging/docker-build-images/install-centos-build-deps diff --git a/hack/release/packaging/docker-build-images/install-ubuntu-build-deps b/release/packaging/docker-build-images/install-ubuntu-build-deps similarity index 100% rename from hack/release/packaging/docker-build-images/install-ubuntu-build-deps rename to release/packaging/docker-build-images/install-ubuntu-build-deps diff --git a/hack/release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.amd64 b/release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.amd64 similarity index 100% rename from hack/release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.amd64 rename to release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.amd64 diff --git a/hack/release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.ppc64le b/release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.ppc64le similarity index 100% rename from hack/release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.ppc64le rename to release/packaging/docker-build-images/ubuntu-focal-build.Dockerfile.ppc64le diff --git a/hack/release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.amd64 b/release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.amd64 similarity index 100% rename from hack/release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.amd64 rename to release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.amd64 diff --git a/hack/release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.ppc64le b/release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.ppc64le similarity index 100% rename from hack/release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.ppc64le rename to release/packaging/docker-build-images/ubuntu-jammy-build.Dockerfile.ppc64le diff --git a/hack/release/packaging/etcd3gw/rpm/python-etcd3gw.spec b/release/packaging/etcd3gw/rpm/python-etcd3gw.spec similarity index 100% rename from hack/release/packaging/etcd3gw/rpm/python-etcd3gw.spec rename to release/packaging/etcd3gw/rpm/python-etcd3gw.spec diff --git a/hack/release/packaging/rpm/build-rpms b/release/packaging/rpm/build-rpms similarity index 85% rename from hack/release/packaging/rpm/build-rpms rename to release/packaging/rpm/build-rpms index 35e877c33ce..92faeb082f0 100755 --- a/hack/release/packaging/rpm/build-rpms +++ b/release/packaging/rpm/build-rpms @@ -54,6 +54,6 @@ esac # Build, and fix centos7 putting always '.centos7' in the rpm-name cd /tmp/rpmbuild rpmbuild --target=$(uname -m) --define '_topdir '`pwd` --define "dist .${EL_VERSION}" -ba SPECS/${spec} -mkdir -p /code/hack/release/packaging/output/dist/rpms-${EL_VERSION}/src -cp -r /tmp/rpmbuild/RPMS/* /code/hack/release/packaging/output/dist/rpms-${EL_VERSION}/ -cp -r /tmp/rpmbuild/SRPMS/* /code/hack/release/packaging/output/dist/rpms-${EL_VERSION}/src/ +mkdir -p /code/release/packaging/output/dist/rpms-${EL_VERSION}/src +cp -r /tmp/rpmbuild/RPMS/* /code/release/packaging/output/dist/rpms-${EL_VERSION}/ +cp -r /tmp/rpmbuild/SRPMS/* /code/release/packaging/output/dist/rpms-${EL_VERSION}/src/ diff --git a/hack/release/packaging/utils/create-update-packages.sh b/release/packaging/utils/create-update-packages.sh similarity index 93% rename from hack/release/packaging/utils/create-update-packages.sh rename to release/packaging/utils/create-update-packages.sh index 55914a507b2..b8cd1805ae4 100755 --- a/hack/release/packaging/utils/create-update-packages.sh +++ b/release/packaging/utils/create-update-packages.sh @@ -25,7 +25,7 @@ rootdir=`git_repo_root` # Directory to copy package build output to. Ensure it exists # and is empty before each build. -outputDir=${rootdir}/hack/release/packaging/output/ +outputDir=${rootdir}/release/packaging/output/ rm -rf ${outputDir} && mkdir -p ${outputDir} pub_steps= @@ -171,7 +171,7 @@ function docker_run_rm { function do_bld_images { # Build the docker images that we use for building for each target platform. - pushd ${rootdir}/hack/release/packaging/docker-build-images + pushd ${rootdir}/release/packaging/docker-build-images docker buildx bake --set centos7.args.UID=$(id -u) --set centos7.args.GID=$(id -g) popd } @@ -182,7 +182,7 @@ function do_net_cal { PKG_NAME=networking-calico \ NAME=networking-calico \ DEB_EPOCH=2: \ - ${rootdir}/hack/release/packaging/utils/make-packages.sh deb rpm + ${rootdir}/release/packaging/utils/make-packages.sh deb rpm # Packages are produced in rootDir/ - move them to the output dir. find ../ -type f -name 'networking-calico_*-*' -exec mv '{}' $outputDir \; # Revert the changes made to networking-calico as part of the package build. @@ -214,7 +214,7 @@ function do_felix { RPM_TAR_ARGS='--exclude=bin/calico-felix-* --exclude=.gitignore --exclude=*.d --exclude=*.ll --exclude=.go-pkg-cache --exclude=vendor --exclude=report' \ DPKG_EXCL="-I'bin/calico-felix-*' -I.git -I.gitignore -I'*.d' -I'*.ll' -I.go-pkg-cache -I.git -Ivendor -Ireport" \ DEB_EPOCH=2: \ - ${rootdir}/hack/release/packaging/utils/make-packages.sh rpm deb + ${rootdir}/release/packaging/utils/make-packages.sh rpm deb git checkout Makefile @@ -224,10 +224,10 @@ function do_felix { } function do_etcd3gw { - pushd ${rootdir}/hack/release/packaging/etcd3gw + pushd ${rootdir}/release/packaging/etcd3gw if ${PACKAGE_ETCD3GW:-false}; then # When PACKAGE_ETCD3GW is explicitly specified, build RPM Python 2 packages for etcd3gw. - PKG_NAME=python-etcd3gw ${rootdir}/hack/release/packaging/utils/make-packages.sh rpm + PKG_NAME=python-etcd3gw ${rootdir}/release/packaging/utils/make-packages.sh rpm else # Otherwise, no-op. We don't have Python 3 RPM packaging for etcd3gw, so it makes sense to # retreat to the same solution as for Debian/Ubuntu: don't build etcd3gw packages, and @@ -246,7 +246,7 @@ function do_dnsmasq { # CentOS/RHEL 7 git checkout origin/rpm_2.79 - docker_run_rm -e EL_VERSION=el7 calico-build/centos7 /code/hack/release/packaging/rpm/build-rpms + docker_run_rm -e EL_VERSION=el7 calico-build/centos7 /code/release/packaging/rpm/build-rpms # Packages are produced in rootDir/ - move them to the output dir. find ../ -type f -name 'dnsmasq_*-*' -exec mv '{}' $outputDir \; @@ -259,7 +259,7 @@ function do_dnsmasq { function do_pub_debs { # Publish Debian packages. - pushd ${rootdir}/hack/release/packaging/output + pushd ${rootdir}/release/packaging/output ../utils/publish-debs.sh popd } @@ -270,7 +270,7 @@ function do_pub_rpms { # Publish RPM packages. Note, this includes updating the RPM repo # metadata. - pushd ${rootdir}/hack/release/packaging/output + pushd ${rootdir}/release/packaging/output ../utils/publish-rpms.sh popd } diff --git a/hack/release/packaging/utils/lib.sh b/release/packaging/utils/lib.sh similarity index 98% rename from hack/release/packaging/utils/lib.sh rename to release/packaging/utils/lib.sh index 72333e66a41..58c6b482411 100644 --- a/hack/release/packaging/utils/lib.sh +++ b/release/packaging/utils/lib.sh @@ -145,7 +145,7 @@ function copy_rpms_to_host { rootdir=`git_repo_root` shopt -s nullglob for arch in src noarch x86_64; do - set -- `find ${rootdir}/hack/release/packaging/output/dist/rpms-el7 -name "*.$arch.rpm"` + set -- `find ${rootdir}/release/packaging/output/dist/rpms-el7 -name "*.$arch.rpm"` if test $# -gt 0; then $ssh_host -- mkdir -p $rpmdir/$reponame/$arch/ $scp_host "$@" ${HOST}:$rpmdir/$reponame/$arch/ diff --git a/hack/release/packaging/utils/make-packages.sh b/release/packaging/utils/make-packages.sh similarity index 100% rename from hack/release/packaging/utils/make-packages.sh rename to release/packaging/utils/make-packages.sh diff --git a/hack/release/packaging/utils/publish-debs.sh b/release/packaging/utils/publish-debs.sh similarity index 85% rename from hack/release/packaging/utils/publish-debs.sh rename to release/packaging/utils/publish-debs.sh index f0237f3b175..9bab5cd0ec9 100755 --- a/hack/release/packaging/utils/publish-debs.sh +++ b/release/packaging/utils/publish-debs.sh @@ -17,7 +17,7 @@ else # -ti to docker-run, and $SECRET_KEY must not require a pass phrase. interactive= fi -docker run --rm ${interactive} -v ${rootdir}:/code -v ${keydir}:/keydir -w /code/hack/release/packaging/output calico-build/focal /bin/sh -c "gpg --import --batch < /keydir/key && debsign -k'*@' --re-sign *_*_source.changes" +docker run --rm ${interactive} -v ${rootdir}:/code -v ${keydir}:/keydir -w /code/release/packaging/output calico-build/focal /bin/sh -c "gpg --import --batch < /keydir/key && debsign -k'*@' --re-sign *_*_source.changes" for series in focal jammy; do # Get the packages and versions that already exist in the PPA, so we can avoid @@ -38,6 +38,6 @@ for series in focal jammy; do break fi done - ${already_exists} || docker run --rm -v ${rootdir}:/code -w /code/hack/release/packaging/output calico-build/${series} dput -u ppa:project-calico/${REPO_NAME} ${changes_file} | ts "[upload $series]" + ${already_exists} || docker run --rm -v ${rootdir}:/code -w /code/release/packaging/output calico-build/${series} dput -u ppa:project-calico/${REPO_NAME} ${changes_file} | ts "[upload $series]" done done diff --git a/hack/release/packaging/utils/publish-rpms.sh b/release/packaging/utils/publish-rpms.sh similarity index 100% rename from hack/release/packaging/utils/publish-rpms.sh rename to release/packaging/utils/publish-rpms.sh diff --git a/hack/release/pkg/builder/builder.go b/release/pkg/builder/builder.go similarity index 57% rename from hack/release/pkg/builder/builder.go rename to release/pkg/builder/builder.go index 55466adade5..eb26887552e 100644 --- a/hack/release/pkg/builder/builder.go +++ b/release/pkg/builder/builder.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tigera, Inc. All rights reserved. +// Copyright (c) 2021-2024 Tigera, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,17 +17,20 @@ package builder import ( "fmt" "os" + "path/filepath" "strings" "github.com/coreos/go-semver/semver" "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" + + "github.com/projectcalico/calico/release/internal/command" ) // Global configuration for releases. var ( - // Registries to which all release images are pushed. - registries = []string{ + // Default defaultRegistries to which all release images are pushed. + defaultRegistries = []string{ "docker.io/calico", "quay.io/calico", "gcr.io/projectcalico-org", @@ -37,20 +40,91 @@ var ( } // Git configuration for publishing to GitHub. - organization = "projectcalico" - repo = "calico" - origin = "origin" + org = "projectcalico" + repo = "calico" + origin = "origin" ) -func NewReleaseBuilder(runner CommandRunner) *ReleaseBuilder { - return &ReleaseBuilder{ - runner: runner, +func NewReleaseBuilder(opts ...Option) *ReleaseBuilder { + // Configure defaults here. + b := &ReleaseBuilder{ + runner: &command.RealCommandRunner{}, + validate: true, + publishImages: true, + publishTag: true, + publishGithub: true, + imageRegistries: defaultRegistries, + githubOrg: org, + } + + // Run through provided options. + for _, o := range opts { + if err := o(b); err != nil { + logrus.WithError(err).Fatal("Failed to apply option to release builder") + } + } + + // Validate the resulting configuration. + if b.repoRoot == "" { + logrus.Fatal("No repo root specified") + } + logrus.WithField("repoRoot", b.repoRoot).Info("Using repo root") + + if b.calicoVersion == "" { + logrus.Fatal("No calico version specified") } + logrus.WithField("version", b.calicoVersion).Info("Using product version") + + if b.operatorVersion == "" { + logrus.Fatal("No operator version specified") + } + if len(b.imageRegistries) == 0 { + logrus.Fatal("No image registries specified") + } + logrus.WithField("operatorVersion", b.operatorVersion).Info("Using operator version") + return b } type ReleaseBuilder struct { // Allow specification of command runner so it can be overridden in tests. - runner CommandRunner + runner command.CommandRunner + + // The abs path of the root of the repository. + repoRoot string + + // isHashRelease is a flag to indicate that we should build a hashrelease. + isHashRelease bool + + // buildImages controls whether we should build container images, or use ones already built by CI. + buildImages bool + + // validate is a flag to indicate that we should skip pre-release validation. + validate bool + + // calicoVersion is the version of calico to release. + calicoVersion string + + // operatorVersion is the version of the operator to release. + operatorVersion string + + // outputDir is the directory to which we should write release artifacts, and from + // which we should read them for publishing. + outputDir string + + // Fine-tuning configuration for publishing. + publishImages bool + publishTag bool + publishGithub bool + + // imageRegistries is the list of imageRegistries to which we should publish images. + imageRegistries []string + + // githubOrg is the GitHub organization to which we should publish releases. + githubOrg string + + // architectures is the list of architectures for which we should build images. + // If empty, we build for all. + architectures []string } // releaseImages returns the set of images that should be expected for a release. @@ -74,6 +148,87 @@ func releaseImages(version, operatorVersion string) []string { } } +func (r *ReleaseBuilder) Build() error { + ver := r.calicoVersion + + // Make sure output directory exists. + var err error + if err = os.MkdirAll(r.uploadDir(), os.ModePerm); err != nil { + return fmt.Errorf("failed to create output dir: %s", err) + } + + if !r.isHashRelease { + if r.validate { + if err = r.PreReleaseValidate(ver); err != nil { + return err + } + } + + // Only tag release if this is not a hashrelease. + // TODO: Option to skip producing a tag, for development. + if err = r.TagRelease(ver); err != nil { + return err + } + + // Successfully tagged. If we fail to release after this stage, we need to delete the tag. + defer func() { + if err != nil { + logrus.WithError(err).Warn("Failed to release, cleaning up tag") + if err := r.DeleteTag(ver); err != nil { + logrus.WithError(err).Error("Failed to clean up tag") + } + } + }() + } + + if r.buildImages { + // Build the container images for the release if configured to do so. + // + // If skipped, we expect that the images for this version have already + // been published as part of CI. + if err = r.BuildContainerImages(ver); err != nil { + return err + } + } + + // Build the helm chart. + if err = r.BuildHelm(); err != nil { + return err + } + + if r.isHashRelease { + // This is a hashrelease. + // + // Re-generate manifests using the desired versions. This needs to happen + // before building the OCP bundle, since the OCP bundle uses the manifests. + if err = r.generateManifests(); err != nil { + return err + } + defer r.resetManifests() + + // Real releases call "make release-build", but hashreleases don't. + // Instead, we build some of the targets directly. In the future, we should instead align the release + // and hashrelease build processes to avoid these separate code paths. + env := append(os.Environ(), fmt.Sprintf("VERSION=%s", ver)) + targets := []string{"release-windows-archive", "dist/install-calico-windows.ps1"} + for _, target := range targets { + if _, err = r.runner.RunInDir(r.repoRoot, "make", []string{"-C", "node", target}, env); err != nil { + return fmt.Errorf("error building target %s: %s", target, err) + } + } + } + + // Build an OCP tgz bundle from manifests, used in the docs. + if err = r.buildOCPBundle(); err != nil { + return err + } + + if err = r.collectGithubArtifacts(); err != nil { + return err + } + return nil +} + func (r *ReleaseBuilder) BuildMetadata(dir string) error { type metadata struct { Version string `json:"version"` @@ -82,15 +237,11 @@ func (r *ReleaseBuilder) BuildMetadata(dir string) error { HelmChartVersion string `json:"helm_chart_version" yaml:"helmChartVersion"` } - // Determine the versions to use based on the manifests, which should - // have already been updated with the correct tags. - calicoVersion, operatorVersion := r.getVersionsFromManifests() - m := metadata{ - Version: calicoVersion, - OperatorVersion: operatorVersion, - Images: releaseImages(calicoVersion, operatorVersion), - HelmChartVersion: calicoVersion, + Version: r.calicoVersion, + OperatorVersion: r.operatorVersion, + Images: releaseImages(r.calicoVersion, r.operatorVersion), + HelmChartVersion: r.calicoVersion, } // Render it as yaml and write it to a file. @@ -107,8 +258,7 @@ func (r *ReleaseBuilder) BuildMetadata(dir string) error { return nil } -// BuildRelease creates a Calico release. -func (r *ReleaseBuilder) BuildRelease() error { +func (r *ReleaseBuilder) PreReleaseValidate(ver string) error { // Check that we're not already on a git tag. out, err := r.git("describe", "--exact-match", "--tags", "HEAD") if err == nil { @@ -125,69 +275,87 @@ func (r *ReleaseBuilder) BuildRelease() error { return fmt.Errorf("Attempt to release from a shallow clone is not possible") } - // Check that the environment has the necessary prereqs. - if err := r.releasePrereqs(); err != nil { - return err - } - - // Determine the last tag on this branch. - out, err = r.git("describe", "--tags", "--dirty", "--always", "--abbrev=12") + // Assert that manifests are using the correct version. + err = r.assertManifestVersions(ver) if err != nil { - logrus.WithError(err).Fatal("Failed to git describe") + return err } - logrus.WithField("out", out).Info("Current git describe") - // Determine the release version to use based on the last tag. - ver, err := r.determineReleaseVersion(out) + err = r.assertReleaseNotesPresent(ver) if err != nil { return err } - err = r.assertReleaseNotesPresent(ver) - if err != nil { + // Check that the environment has the necessary prereqs. + if err := r.releasePrereqs(); err != nil { return err } + return nil +} - // Assert that manifests are using the correct version. - err = r.assertManifestVersions(ver) +func (r *ReleaseBuilder) DeleteTag(ver string) error { + _, err := r.git("tag", "-d", ver) if err != nil { - return err + return fmt.Errorf("Failed to delete tag: %s", err) } + return nil +} +func (r *ReleaseBuilder) TagRelease(ver string) error { branch := r.determineBranch() logrus.WithFields(logrus.Fields{"branch": branch, "version": ver}).Infof("Creating Calico release from branch") - _, err = r.git("tag", ver) + _, err := r.git("tag", ver) if err != nil { return fmt.Errorf("Failed to tag release: %s", err) } + return nil +} - // Successfully tagged. If we fail to release after this stage, we need to delete the tag. - defer func() { - if err != nil { - logrus.WithError(err).Warn("Failed to release, cleaning up tag") - r.git("tag", "-d", ver) - } - }() - +func (r *ReleaseBuilder) BuildContainerImages(ver string) error { // Build container images for the release. - if err = r.buildContainerImages(ver); err != nil { + if err := r.buildContainerImages(ver); err != nil { return err } - - // Build the helm charts - r.runner.Run("make", []string{"chart"}, []string{}) - - // Build OpenShift bundle. - r.runner.Run("make", []string{"bin/ocp.tgz"}, []string{}) - // TODO: Assert the produced images are OK. e.g., have correct // commit and version information compiled in. + return nil +} - // Build artifacts to upload to github. - if err = r.collectGithubArtifacts(ver); err != nil { +func (r *ReleaseBuilder) BuildHelm() error { + if r.isHashRelease { + // We need to modify values.yaml to use the correct version. + valuesYAML := filepath.Join(r.repoRoot, "charts", "tigera-operator", "values.yaml") + if _, err := r.runner.Run("sed", []string{"-i", fmt.Sprintf(`s/version: .*/version: %s/g`, r.operatorVersion), valuesYAML}, nil); err != nil { + logrus.WithError(err).Error("Failed to update operator version in values.yaml") + return err + } + if _, err := r.runner.Run("sed", []string{"-i", fmt.Sprintf(`s/tag: .*/tag: %s/g`, r.calicoVersion), valuesYAML}, nil); err != nil { + logrus.WithError(err).Error("Failed to update calicoctl version in values.yaml") + return err + } + } + + // Build the helm chart, passing the version to use. + env := append(os.Environ(), fmt.Sprintf("GIT_VERSION=%s", r.calicoVersion)) + if _, err := r.runner.RunInDir(r.repoRoot, "make", []string{"chart"}, env); err != nil { return err } + if r.isHashRelease { + // If we modified the repo above, reset it. + if _, err := r.runner.RunInDir(r.repoRoot, "git", []string{"checkout", "charts/tigera-operator"}, nil); err != nil { + logrus.WithError(err).Error("Failed to reset changes to charts") + return err + } + } + return nil +} + +func (r *ReleaseBuilder) buildOCPBundle() error { + // Build OpenShift bundle. + if _, err := r.runner.RunInDir(r.repoRoot, "make", []string{"bin/ocp.tgz"}, []string{}); err != nil { + return err + } return nil } @@ -199,7 +367,7 @@ func (r *ReleaseBuilder) PublishRelease() error { } // Check that the environment has the necessary prereqs. - if err = r.publishPrereqs(ver); err != nil { + if err = r.publishPrereqs(); err != nil { return err } @@ -208,9 +376,11 @@ func (r *ReleaseBuilder) PublishRelease() error { return fmt.Errorf("failed to publish container images: %s", err) } - // If all else is successful, push the git tag. - if _, err = r.git("push", origin, ver); err != nil { - return fmt.Errorf("failed to push git tag: %s", err) + if r.publishTag { + // If all else is successful, push the git tag. + if _, err = r.git("push", origin, ver); err != nil { + return fmt.Errorf("failed to push git tag: %s", err) + } } // Publish the release to github. @@ -221,7 +391,7 @@ func (r *ReleaseBuilder) PublishRelease() error { return nil } -func (r *ReleaseBuilder) NewBranch() error { +func (r *ReleaseBuilder) NewBranch(publish bool) error { // Check that we're on the master branch. We always cut branches from master. branch := r.determineBranch() if branch != "master" { @@ -254,15 +424,18 @@ func (r *ReleaseBuilder) NewBranch() error { // Create a new branch from the current master. r.gitOrFail("checkout", "-b", branchName) - r.gitOrFail("push", origin, branchName) + if publish { + r.gitOrFail("push", origin, branchName) + } // Create the new dev tag on master and push it. r.gitOrFail("checkout", "master") r.gitOrFail("commit", "--allow-empty", "-m", fmt.Sprintf("Begin development on %s", nextVersion)) r.gitOrFail("tag", newDevTag) - r.gitOrFail("push", origin, "master") - r.gitOrFail("push", origin, newDevTag) - + if publish { + r.gitOrFail("push", origin, "master") + r.gitOrFail("push", origin, newDevTag) + } return nil } @@ -286,7 +459,7 @@ func (r *ReleaseBuilder) releasePrereqs() error { } // Prerequisites specific to publishing a release. -func (r *ReleaseBuilder) publishPrereqs(ver string) error { +func (r *ReleaseBuilder) publishPrereqs() error { // TODO: Verify all required artifacts are present. return r.releasePrereqs() } @@ -299,62 +472,71 @@ func (r *ReleaseBuilder) publishPrereqs(ver string) error { // - calico-windows-vX.Y.Z.zip: Calico for Windows zip archive for non-HPC installation. // - calicoctl/bin: All calicoctl binaries. // +// For hashreleases, we don't build the release tarball, but we do include the manifests directly. +// // This function also generates checksums for each artifact that is uploaded to the release. -func (r *ReleaseBuilder) collectGithubArtifacts(ver string) error { - // Final artifacts will be moved here. - uploadDir := r.uploadDir(ver) - // TODO: Delete if already exists. - err := os.MkdirAll(uploadDir, os.ModePerm) - if err != nil { - return fmt.Errorf("failed to create dir: %s", err) - } +func (r *ReleaseBuilder) collectGithubArtifacts() error { + // Artifacts will be moved here. + uploadDir := r.uploadDir() // Add in a release metadata file. - err = r.BuildMetadata(uploadDir) + err := r.BuildMetadata(uploadDir) if err != nil { return fmt.Errorf("failed to build release metadata file: %s", err) } // We attach calicoctl binaries directly to the release as well. - files, err := os.ReadDir("calicoctl/bin/") - if err != nil { - return err - } - for _, b := range files { - if _, err := r.runner.Run("cp", []string{fmt.Sprintf("calicoctl/bin/%s", b.Name()), uploadDir}, nil); err != nil { + if !r.isHashRelease { + // TODO: We don't currently build calicoctl for hashreleases. + files, err := os.ReadDir(filepath.Join(r.repoRoot, "calicoctl", "bin")) + if err != nil { return err } - } + for _, b := range files { + if _, err := r.runner.Run("cp", []string{filepath.Join(r.repoRoot, "calicoctl", "bin", b.Name()), uploadDir}, nil); err != nil { + return err + } + } - // Build and add in the complete release tarball. - if err = r.buildReleaseTar(ver, uploadDir); err != nil { - return err + // Build and add in the complete release tarball. + if err = r.buildReleaseTar(r.calicoVersion, uploadDir); err != nil { + return err + } + } else { + // Hashrelease - output dir is a little different for now. + // TODO: Manifests included here, instead of in release tarball. + if _, err := r.runner.Run("cp", []string{"-r", filepath.Join(r.repoRoot, "manifests"), uploadDir}, nil); err != nil { + logrus.WithError(err).Error("Failed to copy manifests to output directory") + return err + } } // Add in the already-built windows zip archive, the Windows install script, ocp bundle, and the helm chart. - if _, err := r.runner.Run("cp", []string{fmt.Sprintf("node/dist/calico-windows-%s.zip", ver), uploadDir}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "cp", []string{fmt.Sprintf("node/dist/calico-windows-%s.zip", r.calicoVersion), uploadDir}, nil); err != nil { return err } - if _, err := r.runner.Run("cp", []string{"node/dist/install-calico-windows.ps1", uploadDir}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "cp", []string{"node/dist/install-calico-windows.ps1", uploadDir}, nil); err != nil { return err } - if _, err := r.runner.Run("cp", []string{fmt.Sprintf("bin/tigera-operator-%s.tgz", ver), uploadDir}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "cp", []string{"bin/ocp.tgz", uploadDir}, nil); err != nil { return err } - if _, err := r.runner.Run("cp", []string{"bin/ocp.tgz", uploadDir}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "cp", []string{fmt.Sprintf("bin/tigera-operator-%s.tgz", r.calicoVersion), uploadDir}, nil); err != nil { return err } // Generate a SHA256SUMS file containing the checksums for each artifact // that we attach to the release. These can be confirmed by end users via the following command: // sha256sum -c --ignore-missing SHA256SUMS - files, err = os.ReadDir(uploadDir) + files, err := os.ReadDir(uploadDir) if err != nil { return err } sha256args := []string{} for _, f := range files { - sha256args = append(sha256args, f.Name()) + if !f.IsDir() { + sha256args = append(sha256args, f.Name()) + } } output, err := r.runner.RunInDir(uploadDir, "sha256sum", sha256args, nil) if err != nil { @@ -368,8 +550,29 @@ func (r *ReleaseBuilder) collectGithubArtifacts(ver string) error { return nil } -func (r *ReleaseBuilder) uploadDir(ver string) string { - return fmt.Sprintf("_output/upload/%s", ver) +// generateManifests re-generates manifests using the specified calico and operator versions. +func (r *ReleaseBuilder) generateManifests() error { + env := os.Environ() + env = append(env, fmt.Sprintf("CALICO_VERSION=%s", r.calicoVersion)) + env = append(env, fmt.Sprintf("OPERATOR_VERSION=%s", r.operatorVersion)) + if _, err := r.runner.RunInDir(r.repoRoot, "make", []string{"gen-manifests"}, env); err != nil { + logrus.WithError(err).Error("Failed to make manifests") + return err + } + return nil +} + +func (r *ReleaseBuilder) resetManifests() { + if _, err := r.runner.RunInDir(r.repoRoot, "git", []string{"checkout", "manifests"}, nil); err != nil { + logrus.WithError(err).Error("Failed to reset manifests") + } +} + +func (r *ReleaseBuilder) uploadDir() string { + if r.outputDir == "" { + logrus.Panic("No output directory specified") + } + return r.outputDir } // Builds the complete release tar for upload to github. @@ -378,32 +581,31 @@ func (r *ReleaseBuilder) uploadDir(ver string) string { // TODO: We should produce windows tars func (r *ReleaseBuilder) buildReleaseTar(ver string, targetDir string) error { // Create tar files for container image that are shipped. - releaseBase := fmt.Sprintf("_output/release-%s", ver) + releaseBase := filepath.Join(r.repoRoot, "release", "_output", fmt.Sprintf("release-%s", ver)) err := os.MkdirAll(releaseBase+"/images", os.ModePerm) if err != nil { return fmt.Errorf("Failed to create images dir: %s", err) } - outFmt := "_output/release-%s/images/%s" - registry := registries[0] + imgDir := filepath.Join(releaseBase, "images") + registry := r.imageRegistries[0] images := map[string]string{ - fmt.Sprintf("%s/node:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-node.tar"), - fmt.Sprintf("%s/typha:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-typha.tar"), - fmt.Sprintf("%s/cni:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-cni.tar"), - fmt.Sprintf("%s/kube-controllers:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-kube-controllers.tar"), - fmt.Sprintf("%s/pod2daemon-flexvol:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-pod2daemon.tar"), - fmt.Sprintf("%s/dikastes:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-dikastes.tar"), - fmt.Sprintf("%s/flannel-migration-controller:%s", registry, ver): fmt.Sprintf(outFmt, ver, "calico-flannel-migration-controller.tar"), + fmt.Sprintf("%s/node:%s", registry, ver): filepath.Join(imgDir, "calico-node.tar"), + fmt.Sprintf("%s/typha:%s", registry, ver): filepath.Join(imgDir, "calico-typha.tar"), + fmt.Sprintf("%s/cni:%s", registry, ver): filepath.Join(imgDir, "calico-cni.tar"), + fmt.Sprintf("%s/kube-controllers:%s", registry, ver): filepath.Join(imgDir, "calico-kube-controllers.tar"), + fmt.Sprintf("%s/pod2daemon-flexvol:%s", registry, ver): filepath.Join(imgDir, "calico-pod2daemon.tar"), + fmt.Sprintf("%s/dikastes:%s", registry, ver): filepath.Join(imgDir, "calico-dikastes.tar"), + fmt.Sprintf("%s/flannel-migration-controller:%s", registry, ver): filepath.Join(imgDir, "calico-flannel-migration-controller.tar"), } for img, out := range images { err = r.archiveContainerImage(out, img) if err != nil { return err } - } // Add in release binaries that we ship. - binDir := fmt.Sprintf("%s/bin", releaseBase) + binDir := filepath.Join(releaseBase, "bin") err = os.MkdirAll(binDir, os.ModePerm) if err != nil { return fmt.Errorf("Failed to create images dir: %s", err) @@ -411,10 +613,10 @@ func (r *ReleaseBuilder) buildReleaseTar(ver string, targetDir string) error { binaries := map[string]string{ // CNI plugin binaries are all placed in github dir. - "cni-plugin/bin/": binDir + "/cni", + "cni-plugin/bin/": filepath.Join(binDir, "cni"), // Calicoctl binaries. - "calicoctl/bin/": binDir + "/calicoctl", + "calicoctl/bin/": filepath.Join(binDir, "calicoctl"), // Felix binaries. "felix/bin/calico-bpf": binDir, @@ -426,15 +628,15 @@ func (r *ReleaseBuilder) buildReleaseTar(ver string, targetDir string) error { } // Add in manifests directory generated from the docs. - if _, err := r.runner.Run("cp", []string{"-r", "manifests", releaseBase}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "cp", []string{"-r", "manifests", releaseBase}, nil); err != nil { return err } // tar up the whole thing, and copy it to the target directory - if _, err := r.runner.Run("tar", []string{"-czvf", fmt.Sprintf("_output/release-%s.tgz", ver), "-C", "_output", fmt.Sprintf("release-%s", ver)}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "tar", []string{"-czvf", fmt.Sprintf("release/_output/release-%s.tgz", ver), "-C", "release/_output", fmt.Sprintf("release-%s", ver)}, nil); err != nil { return err } - if _, err := r.runner.Run("cp", []string{fmt.Sprintf("_output/release-%s.tgz", ver), targetDir}, nil); err != nil { + if _, err := r.runner.RunInDir(r.repoRoot, "cp", []string{fmt.Sprintf("release/_output/release-%s.tgz", ver), targetDir}, nil); err != nil { return err } return nil @@ -461,11 +663,16 @@ func (r *ReleaseBuilder) buildContainerImages(ver string) error { // Build env. env := append(os.Environ(), fmt.Sprintf("VERSION=%s", ver), - fmt.Sprintf("DEV_REGISTRIES=%s", strings.Join(registries, " ")), + fmt.Sprintf("DEV_REGISTRIES=%s", strings.Join(r.imageRegistries, " ")), ) + if len(r.architectures) > 0 { + env = append(env, fmt.Sprintf("ARCHES=%s", strings.Join(r.architectures, " "))) + } + for _, dir := range releaseDirs { - out, err := r.makeInDirectoryWithOutput(dir, "release-build", env...) + // Use an absolute path for the directory to build. + out, err := r.makeInDirectoryWithOutput(filepath.Join(r.repoRoot, dir), "release-build", env...) if err != nil { logrus.Error(out) return fmt.Errorf("Failed to build %s: %s", dir, err) @@ -474,7 +681,7 @@ func (r *ReleaseBuilder) buildContainerImages(ver string) error { } for _, dir := range windowsReleaseDirs { - out, err := r.makeInDirectoryWithOutput(dir, "image-windows", env...) + out, err := r.makeInDirectoryWithOutput(filepath.Join(r.repoRoot, dir), "image-windows", env...) if err != nil { logrus.Error(out) return fmt.Errorf("Failed to build %s: %s", dir, err) @@ -485,6 +692,11 @@ func (r *ReleaseBuilder) buildContainerImages(ver string) error { } func (r *ReleaseBuilder) publishGithubRelease(ver string) error { + if !r.publishGithub { + logrus.Info("Skipping github release") + return nil + } + releaseNoteTemplate := ` Release notes can be found [on GitHub](https://github.com/projectcalico/calico/blob/{version}/release-notes/{version}-release-notes.md) @@ -518,18 +730,23 @@ Additional links: releaseNote := replacer.Replace(releaseNoteTemplate) args := []string{ - "-username", organization, + "-username", r.githubOrg, "-repository", repo, "-name", ver, "-body", releaseNote, ver, - r.uploadDir(ver), + r.uploadDir(), } - _, err = r.runner.Run("./hack/release/ghr", args, nil) + _, err = r.runner.RunInDir(r.repoRoot, "./bin/ghr", args, nil) return err } func (r *ReleaseBuilder) publishContainerImages(ver string) error { + if !r.publishImages { + logrus.Info("Skipping image publish") + return nil + } + releaseDirs := []string{ "pod2daemon", "cni-plugin", @@ -551,7 +768,7 @@ func (r *ReleaseBuilder) publishContainerImages(ver string) error { fmt.Sprintf("VERSION=%s", ver), "RELEASE=true", "CONFIRM=true", - fmt.Sprintf("DEV_REGISTRIES=%s", strings.Join(registries, " ")), + fmt.Sprintf("DEV_REGISTRIES=%s", strings.Join(r.imageRegistries, " ")), ) // We allow for a certain number of retries when publishing each directory, since @@ -560,7 +777,7 @@ func (r *ReleaseBuilder) publishContainerImages(ver string) error { for _, dir := range releaseDirs { attempt := 0 for { - out, err := r.makeInDirectoryWithOutput(dir, "release-publish", env...) + out, err := r.makeInDirectoryWithOutput(filepath.Join(r.repoRoot, dir), "release-publish", env...) if err != nil { if attempt < maxRetries { logrus.WithField("attempt", attempt).WithError(err).Warn("Publish failed, retrying") @@ -579,7 +796,7 @@ func (r *ReleaseBuilder) publishContainerImages(ver string) error { for _, dir := range windowsReleaseDirs { attempt := 0 for { - out, err := r.makeInDirectoryWithOutput(dir, "release-windows", env...) + out, err := r.makeInDirectoryWithOutput(filepath.Join(r.repoRoot, dir), "release-windows", env...) if err != nil { if attempt < maxRetries { logrus.WithField("attempt", attempt).WithError(err).Warn("Publish failed, retrying") @@ -604,7 +821,6 @@ func (r *ReleaseBuilder) assertReleaseNotesPresent(ver string) error { releaseNotesPath := fmt.Sprintf("release-notes/%s-release-notes.md", ver) releaseNotesStat, err := os.Stat(releaseNotesPath) - // If we got an error, handle that? if err != nil { return fmt.Errorf("release notes file is invalid: %s", err.Error()) @@ -625,7 +841,7 @@ func (r *ReleaseBuilder) assertManifestVersions(ver string) error { for _, m := range manifests { args := []string{"-Po", `image:\K(.*)`, m} - out, err := r.runner.RunInDir("manifests", "grep", args, nil) + out, err := r.runner.RunInDir(filepath.Join(r.repoRoot, "manifests"), "grep", args, nil) if err != nil { return err } @@ -645,71 +861,6 @@ func (r *ReleaseBuilder) assertManifestVersions(ver string) error { return nil } -// getVersionsFromManifests returns the Calico and Operator versions in-use by this -// release based on the generated manifests to be used for this release. -func (r *ReleaseBuilder) getVersionsFromManifests() (string, string) { - manifests := []string{"calico.yaml", "tigera-operator.yaml"} - - var operatorVersion, version string - for _, m := range manifests { - args := []string{"-Po", `image:\K(.*)`, m} - out, err := r.runner.RunInDir("manifests", "grep", args, nil) - if err != nil { - panic(err) - } - - imgs := strings.Split(out, "\n") - - for _, i := range imgs { - if strings.Contains(i, "operator") && operatorVersion == "" { - splits := strings.SplitAfter(i, ":") - operatorVersion = splits[len(splits)-1] - logrus.Infof("Using version %s from image %s", version, i) - } else if strings.Contains(i, "calico/") && version == "" { - splits := strings.SplitAfter(i, ":") - version = splits[len(splits)-1] - logrus.Infof("Using version %s from image %s", version, i) - } - if operatorVersion != "" && version != "" { - break - } - } - if operatorVersion != "" && version != "" { - break - } - } - - if version == "" || operatorVersion == "" { - panic("Missing version!") - } - - return version, operatorVersion -} - -// determineReleaseVersion uses historical clues to figure out the next semver -// release number to use for this release. -func (r *ReleaseBuilder) determineReleaseVersion(previousTag string) (string, error) { - // There are two types of tag that this might be - either it was a previous patch release, - // or it was a "vX.Y.Z-0.dev" tag produced when cutting the release branch. - if strings.Contains(previousTag, "-0.dev") { - // This is the first release from this branch - we can simply extract the version from - // the dev tag. - return strings.Split(previousTag, "-0.dev")[0], nil - } else { - // This is a patch release - we need to parse the previous, and - // bump the patch version. - previousVersion := strings.Split(previousTag, "-")[0] - logrus.WithField("previousVersion", previousVersion).Info("Previous version") - v, err := semver.NewVersion(strings.TrimPrefix(previousVersion, "v")) - if err != nil { - logrus.WithField("previousVersion", previousVersion).WithError(err).Error("Failed to parse git version as semver") - return "", fmt.Errorf("failed to parse git version as semver: %s", err) - } - v.BumpPatch() - return fmt.Sprintf("v%s", v.String()), nil - } -} - // determineBranch returns the current checked out branch. func (r *ReleaseBuilder) determineBranch() string { out, err := r.git("rev-parse", "--abbrev-ref", "HEAD") @@ -738,15 +889,6 @@ func (r *ReleaseBuilder) gitOrFail(args ...string) { } } -func (r *ReleaseBuilder) makeInDirectory(dir, target string, env ...string) error { - _, err := r.runner.Run("make", []string{"-C", dir, target}, env) - return err -} - func (r *ReleaseBuilder) makeInDirectoryWithOutput(dir, target string, env ...string) (string, error) { return r.runner.Run("make", []string{"-C", dir, target}, env) } - -func (r *ReleaseBuilder) makeInDirectoryNoOutput(dir, target string, env ...string) error { - return r.runner.RunNoCapture("make", []string{"-C", dir, target}, env) -} diff --git a/hack/release/pkg/builder/builder_suite_test.go b/release/pkg/builder/builder_suite_test.go similarity index 100% rename from hack/release/pkg/builder/builder_suite_test.go rename to release/pkg/builder/builder_suite_test.go diff --git a/release/pkg/builder/options.go b/release/pkg/builder/options.go new file mode 100644 index 00000000000..700bf6198a9 --- /dev/null +++ b/release/pkg/builder/options.go @@ -0,0 +1,90 @@ +// Copyright (c) 2024 Tigera, Inc. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package builder + +type Option func(*ReleaseBuilder) error + +func WithRepoRoot(root string) Option { + return func(r *ReleaseBuilder) error { + r.repoRoot = root + return nil + } +} + +func IsHashRelease() Option { + return func(r *ReleaseBuilder) error { + r.isHashRelease = true + return nil + } +} + +func WithPreReleaseValidation(validate bool) Option { + return func(r *ReleaseBuilder) error { + r.validate = validate + return nil + } +} + +func WithVersions(calicoVersion, operatorVersion string) Option { + return func(r *ReleaseBuilder) error { + r.calicoVersion = calicoVersion + r.operatorVersion = operatorVersion + return nil + } +} + +func WithOutputDir(outputDir string) Option { + return func(r *ReleaseBuilder) error { + r.outputDir = outputDir + return nil + } +} + +func WithPublishOptions(images, tag, github bool) Option { + return func(r *ReleaseBuilder) error { + r.publishImages = images + r.publishTag = tag + r.publishGithub = github + return nil + } +} + +func WithBuildImages(buildImages bool) Option { + return func(r *ReleaseBuilder) error { + r.buildImages = buildImages + return nil + } +} + +func WithImageRegistries(registries []string) Option { + return func(r *ReleaseBuilder) error { + r.imageRegistries = registries + return nil + } +} + +func WithArchitectures(architectures []string) Option { + return func(r *ReleaseBuilder) error { + r.architectures = architectures + return nil + } +} + +func WithGithubOrg(org string) Option { + return func(r *ReleaseBuilder) error { + r.githubOrg = org + return nil + } +} diff --git a/release/pkg/tasks/clean.go b/release/pkg/tasks/clean.go new file mode 100644 index 00000000000..e18d26e1e62 --- /dev/null +++ b/release/pkg/tasks/clean.go @@ -0,0 +1,30 @@ +package tasks + +import ( + "os" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/command" +) + +// CleanFiles removes the files at the given paths. +// If a path contains a wildcard, it will be expanded. +// If a path is a directory, it will be removed recursively. +// If a path is a file, it will be removed. +func CleanFiles(paths ...string) { + for _, p := range paths { + err := os.RemoveAll(p) + if err != nil { + logrus.WithField("path", p).WithError(err).Fatal("removing file(s) failed") + } + } +} + +// ResetRepo resets the git repo at the given directory. +func ResetRepo(dir string) { + _, err := command.GitInDir(dir, "checkout", "HEAD") + if err != nil { + logrus.WithError(err).Fatal("failed to reset repo") + } +} diff --git a/release/pkg/tasks/hashrelease.go b/release/pkg/tasks/hashrelease.go new file mode 100644 index 00000000000..0a74ca7bbe9 --- /dev/null +++ b/release/pkg/tasks/hashrelease.go @@ -0,0 +1,275 @@ +package tasks + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/command" + "github.com/projectcalico/calico/release/internal/config" + "github.com/projectcalico/calico/release/internal/hashrelease" + "github.com/projectcalico/calico/release/internal/imagescanner" + "github.com/projectcalico/calico/release/internal/operator" + "github.com/projectcalico/calico/release/internal/registry" + "github.com/projectcalico/calico/release/internal/slack" + "github.com/projectcalico/calico/release/internal/utils" + "github.com/projectcalico/calico/release/internal/version" +) + +// ciURL returns the URL for the CI job. +func ciURL() string { + if os.Getenv("CI") == "true" && os.Getenv("SEMAPHORE") == "true" { + return fmt.Sprintf("https://tigera.semaphoreci.com/jobs/%s", os.Getenv("SEMAPHORE_JOB_ID")) + } + return "" +} + +// PinnedVersion generates pinned-version.yaml +// +// It clones the operator repository, +// then call GeneratePinnedVersion to generate the pinned-version.yaml file. +// The location of the pinned-version.yaml file is logged. +func PinnedVersion(cfg *config.Config) (string, string, string) { + tmpDir := cfg.TmpFolderPath() + if err := os.MkdirAll(tmpDir, utils.DirPerms); err != nil { + logrus.WithError(err).Fatal("Failed to create output directory") + } + operatorConfig := cfg.OperatorConfig + if err := operator.Clone(operatorConfig); err != nil { + logrus.WithFields(logrus.Fields{ + "directory": tmpDir, + "repository": operatorConfig.Repo, + "branch": operatorConfig.Branch, + }).WithError(err).Fatal("Failed to clone operator repository") + } + pinnedVersionFilePath, data, err := hashrelease.GeneratePinnedVersionFile(cfg.RepoRootDir, cfg.RepoReleaseBranchPrefix, cfg.DevTagSuffix, cfg.OperatorConfig, tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to generate pinned-version.yaml") + } + logrus.WithField("file", pinnedVersionFilePath).Info("Generated pinned-version.yaml") + return data.ProductVersion, data.Operator.Version, data.Hash +} + +type imageExistsResult struct { + name string + image string + exists bool + err error +} + +func imgExists(name string, component hashrelease.Component, ch chan imageExistsResult) { + r := imageExistsResult{ + name: name, + image: component.String(), + } + r.exists, r.err = registry.ImageExists(component.ImageRef()) + ch <- r +} + +// HashreleaseValidate validates the images in the hashrelease. +// These images are checked to ensure they exist in the registry +// as they should have been pushed in the standard build process. +func HashreleaseValidate(cfg *config.Config, skipISS bool) { + tmpDir := cfg.TmpFolderPath() + name, err := hashrelease.RetrieveReleaseName(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get release name") + } + productBranch, err := utils.GitBranch(cfg.RepoRootDir) + if err != nil { + logrus.WithError(err).Fatalf("Failed to get %s branch name", utils.ProductName) + } + productVersion, err := hashrelease.RetrievePinnedProductVersion(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get candidate name") + } + operatorVersion, err := hashrelease.RetrievePinnedOperatorVersion(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get operator version") + } + images, err := hashrelease.RetrieveComponentsToValidate(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get pinned version") + } + results := make(map[string]imageExistsResult, len(images)) + + ch := make(chan imageExistsResult) + for name, component := range images { + go imgExists(name, component, ch) + } + for range images { + res := <-ch + results[res.name] = res + } + failedImages := []hashrelease.Component{} + failedImageNames := []string{} + for name, r := range results { + logrus.WithFields(logrus.Fields{ + "image": r.image, + "exists": r.exists, + }).Info("Validating image") + if r.err != nil || !r.exists { + logrus.WithError(r.err).WithField("image", name).Error("Error checking image") + failedImageNames = append(failedImageNames, name) + failedImages = append(failedImages, images[name]) + } else { + logrus.WithField("image", name).Info("Image exists") + } + } + failedCount := len(failedImageNames) + if failedCount > 0 { + ciURL := ciURL() + // We only care to send failure messages if we are in CI + if ciURL != "" { + slackMsg := slack.Message{ + Config: cfg.SlackConfig, + Data: slack.MessageData{ + ReleaseName: name, + Product: utils.DisplayProductName(), + Stream: version.DeterminePublishStream(productBranch, productVersion), + Version: productVersion, + OperatorVersion: operatorVersion, + CIURL: ciURL, + FailedImages: failedImages, + }, + } + if err := slackMsg.SendFailure(logrus.IsLevelEnabled(logrus.DebugLevel)); err != nil { + logrus.WithError(err).Error("Failed to send slack message") + } + } + logrus.WithField("images", strings.Join(failedImageNames, ", ")). + Fatalf("Failed to validate %d images, see above for details", failedCount) + } + if !skipISS { + logrus.Info("Sending images to ISS") + imageList := []string{} + for _, component := range images { + imageList = append(imageList, component.String()) + } + imageScanner := imagescanner.New(cfg.ImageScannerConfig) + err := imageScanner.Scan(imageList, version.DeterminePublishStream(productBranch, productVersion), false, cfg.OutputDir) + if err != nil { + // Error is logged and ignored as this is not considered a fatal error + logrus.WithError(err).Error("Failed to scan images") + } + } +} + +// CheckIfHashReleasePublished checks if the hashrelease has already been published. +// If it has, the process is halted. +func CheckIfHashReleasePublished(cfg *config.Config, hash string) { + if cfg.DocsHost == "" || cfg.DocsUser == "" || cfg.DocsKey == "" || cfg.DocsPort == "" { + // Check if we're running in CI - if so, we should fail if this configuration is missing. + // Otherwise, we should just log and continue. + if os.Getenv("CI") == "true" { + logrus.Fatal("Missing hashrelease server configuration") + } + logrus.Info("Missing hashrelease server configuration, skipping remote hashrelease check") + return + } + + sshConfig := command.NewSSHConfig(cfg.DocsHost, cfg.DocsUser, cfg.DocsKey, cfg.DocsPort) + if hashrelease.Exists(hash, sshConfig) { + logrus.WithField("hash", hash).Fatal("Hashrelease already exists") + } +} + +// HashreleaseValidate publishes the hashrelease +func HashreleasePush(cfg *config.Config, path string) { + tmpDir := cfg.TmpFolderPath() + sshConfig := command.NewSSHConfig(cfg.DocsHost, cfg.DocsUser, cfg.DocsKey, cfg.DocsPort) + name, err := hashrelease.RetrieveReleaseName(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get release name") + } + note, err := hashrelease.RetrievePinnedVersionNote(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get pinned version note") + } + productBranch, err := utils.GitBranch(cfg.RepoRootDir) + if err != nil { + logrus.WithError(err).Fatalf("Failed to get %s branch name", utils.ProductName) + } + productVersion, err := hashrelease.RetrievePinnedProductVersion(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get candidate name") + } + operatorVersion, err := hashrelease.RetrievePinnedOperatorVersion(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get operator version") + } + releaseHash, err := hashrelease.RetrievePinnedVersionHash(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get release hash") + } + logrus.WithField("note", note).Info("Publishing hashrelease") + if err := hashrelease.Publish(name, releaseHash, note, version.DeterminePublishStream(productBranch, productVersion), path, sshConfig); err != nil { + logrus.WithError(err).Fatal("Failed to publish hashrelease") + } + scanResultURL := imagescanner.RetrieveResultURL(cfg.OutputDir) + slackMsg := slack.Message{ + Config: cfg.SlackConfig, + Data: slack.MessageData{ + ReleaseName: name, + Product: utils.DisplayProductName(), + Stream: version.DeterminePublishStream(productBranch, productVersion), + Version: productVersion, + OperatorVersion: operatorVersion, + DocsURL: hashrelease.URL(name), + CIURL: ciURL(), + ImageScanResultURL: scanResultURL, + }, + } + if err := slackMsg.SendSuccess(logrus.IsLevelEnabled(logrus.DebugLevel)); err != nil { + logrus.WithError(err).Error("Failed to send slack message") + } + logrus.WithFields(logrus.Fields{ + "name": name, + "docsURL": hashrelease.URL(name), + }).Info("Published hashrelease") +} + +// HashreleaseCleanRemote cleans up old hashreleases on the docs host +func HashreleaseCleanRemote(cfg *config.Config) { + sshConfig := command.NewSSHConfig(cfg.DocsHost, cfg.DocsUser, cfg.DocsKey, cfg.DocsPort) + logrus.Info("Cleaning up old hashreleases") + if err := hashrelease.DeleteOld(sshConfig); err != nil { + logrus.WithError(err).Fatal("Failed to delete old hashreleases") + } +} + +// ReformatHashrelease modifies the generated release output to match +// the "legacy" format our CI tooling expects. This should be temporary until +// we can update the tooling to expect the new format. +// Specifically, we need to do two things: +// - Copy the windows zip file to files/windows/calico-windows-.zip +// - Copy tigera-operator-.tgz to tigera-operator.tgz +func ReformatHashrelease(cfg *config.Config, dir string) error { + logrus.Info("Modifying hashrelease output to match legacy format") + pinned, err := hashrelease.RetrievePinnedVersion(cfg.TmpFolderPath()) + if err != nil { + return err + } + ver := pinned.Components["calico"].Version + + // Copy the windows zip file to files/windows/calico-windows-.zip + if err := os.MkdirAll(filepath.Join(dir, "files", "windows"), 0o755); err != nil { + return err + } + windowsZip := filepath.Join(dir, fmt.Sprintf("calico-windows-%s.zip", ver)) + windowsZipDst := filepath.Join(dir, "files", "windows", fmt.Sprintf("calico-windows-%s.zip", ver)) + if err := utils.CopyFile(windowsZip, windowsZipDst); err != nil { + return err + } + + // Copy the operator tarball to tigera-operator.tgz + operatorTarball := filepath.Join(dir, fmt.Sprintf("tigera-operator-%s.tgz", ver)) + operatorTarballDst := filepath.Join(dir, "tigera-operator.tgz") + if err := utils.CopyFile(operatorTarball, operatorTarballDst); err != nil { + return err + } + return nil +} diff --git a/release/pkg/tasks/operator.go b/release/pkg/tasks/operator.go new file mode 100644 index 00000000000..d9d0b37d6c8 --- /dev/null +++ b/release/pkg/tasks/operator.go @@ -0,0 +1,85 @@ +package tasks + +import ( + "fmt" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/config" + "github.com/projectcalico/calico/release/internal/hashrelease" + "github.com/projectcalico/calico/release/internal/operator" + "github.com/projectcalico/calico/release/internal/registry" +) + +// OperatorHashreleaseBuild builds the operator images for the hashrelease. +// As images are build with the latest tag, they are re-tagged with the hashrelease version +func OperatorHashreleaseBuild(runner *registry.DockerRunner, cfg *config.Config) { + tmpDir := cfg.TmpFolderPath() + operatorDir := cfg.OperatorConfig.Dir + componentsVersionPath, err := hashrelease.GenerateComponentsVersionFile(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to generate components.yaml") + } + operatorComponent, err := hashrelease.RetrievePinnedOperator(tmpDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to get operator version") + } + if err := operator.GenVersions(componentsVersionPath, operatorDir); err != nil { + logrus.WithError(err).Fatal("Failed to generate versions") + } + logrus.Infof("Building operator images for %v", cfg.Arches) + if err := operator.ImageAll(cfg.Arches, operatorComponent.Version, operatorDir); err != nil { + logrus.WithError(err).Fatal("Failed to build images") + } + logrus.Info("Building operator init image") + operatorInitImage := operatorComponent.InitImage() + if err := operator.InitImage(operatorInitImage.Version, operatorDir); err != nil { + logrus.WithError(err).Fatal("Failed to init images") + } + for _, arch := range cfg.Arches { + currentTag := fmt.Sprintf("%s:latest-%s", operatorComponent.Image, arch) + newTag := fmt.Sprintf("%s-%s", operatorComponent.String(), arch) + logrus.WithFields(logrus.Fields{ + "current tag": currentTag, + "new tag": newTag, + }).Info("Re-tagging operator image") + if err := runner.TagImage(currentTag, newTag); err != nil { + logrus.WithField("image", currentTag).WithError(err).Fatal("Failed to re-tag operator image") + } + } + logrus.Info("Re-tag operator init image") + currentTag := fmt.Sprintf("%s:latest", operatorInitImage.Image) + newTag := operatorComponent.InitImage().String() + if err := runner.TagImage(currentTag, newTag); err != nil { + logrus.WithError(err).Fatal("Failed to tag operator init image") + } +} + +// OperatorHashreleasePush pushes the operator images to the registry +// +// It does this by retrieving the pinned operator version, +// pushing the operator images to the registry, +// then pushing a manifest list of the operator images to the registry. +func OperatorHashreleasePush(runner *registry.DockerRunner, cfg *config.Config) { + operatorComponent, err := hashrelease.RetrievePinnedOperator(cfg.TmpFolderPath()) + if err != nil { + logrus.WithError(err).Fatal("Failed to get operator version") + } + var imageList []string + for _, arch := range cfg.Arches { + imgName := fmt.Sprintf("%s-%s", operatorComponent.String(), arch) + if err := runner.PushImage(imgName); err != nil { + logrus.WithField("image", imgName).WithError(err).Fatal("Failed to push operator image") + } + logrus.WithField("image", imgName).Info("Pushed operator image") + imageList = append(imageList, imgName) + } + manifestListName := operatorComponent.String() + if err = runner.ManifestPush(manifestListName, imageList); err != nil { + logrus.WithField("manifest", manifestListName).WithError(err).Fatal("Failed to push operator manifest") + } + initImage := operatorComponent.InitImage() + if err := runner.PushImage(initImage.String()); err != nil { + logrus.WithField("image", initImage).WithError(err).Fatal("Failed to push operator init image") + } +} diff --git a/release/pkg/tasks/release.go b/release/pkg/tasks/release.go new file mode 100644 index 00000000000..f5a94b7932e --- /dev/null +++ b/release/pkg/tasks/release.go @@ -0,0 +1,46 @@ +package tasks + +import ( + "fmt" + "regexp" + + "github.com/sirupsen/logrus" + + "github.com/projectcalico/calico/release/internal/config" + "github.com/projectcalico/calico/release/internal/outputs" + "github.com/projectcalico/calico/release/internal/utils" + "github.com/projectcalico/calico/release/internal/version" +) + +// ReleaseNotes generates release notes for the current release to outDir. +func ReleaseNotes(cfg *config.Config, outDir string, version version.Version) { + filePath, err := outputs.ReleaseNotes(cfg.Organization, cfg.GithubToken, cfg.RepoRootDir, outDir, version) + if err != nil { + logrus.WithError(err).Fatal("Failed to generate release notes") + } + logrus.WithField("file", filePath).Info("Generated release notes") + logrus.Info("Please review for accuracy, and format appropriately before releasing.") +} + +// PreReleaseValidate validates release configuration before starting a release. +func PreReleaseValidate(cfg *config.Config) { + releaseBranch, err := utils.GitBranch(cfg.RepoRootDir) + if err != nil { + logrus.WithError(err).Fatal("unable to get git branch") + } + match := fmt.Sprintf(`^(%s|%s-v\d+\.\d+(?:-\d+)?)$`, utils.DefaultBranch, cfg.RepoReleaseBranchPrefix) + re := regexp.MustCompile(match) + if !re.MatchString(releaseBranch) { + logrus.WithField("branch", releaseBranch).Fatal("Not on a release branch") + } + dirty, err := utils.GitIsDirty(cfg.RepoRootDir) + if err != nil { + logrus.WithError(err).Fatal("Failed to check if git is dirty") + } else if dirty { + logrus.Fatal("There are uncommitted changes in the repository, please commit or stash them before building the hashrelease") + } + logrus.WithFields(logrus.Fields{ + "releaseBranch": releaseBranch, + "operatorConfig": cfg.OperatorConfig, + }).Info("Pre-release validation complete, ready to release") +} diff --git a/typha/check-licenses/.gitignore b/typha/check-licenses/.gitignore deleted file mode 100644 index 4e8560ec2eb..00000000000 --- a/typha/check-licenses/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dependency-licenses.txt diff --git a/typha/check-licenses/check_licenses.go b/typha/check-licenses/check_licenses.go deleted file mode 100644 index 449fe2635e2..00000000000 --- a/typha/check-licenses/check_licenses.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "bufio" - "os" - "regexp" - "strings" - - log "github.com/sirupsen/logrus" - - "github.com/projectcalico/calico/libcalico-go/lib/set" - "github.com/projectcalico/calico/typha/pkg/logutils" -) - -var ( - approvedLicenses = set.From( - "Apache License 2.0", - "MIT License", - "ISC License", - "BSD 3-clause \"New\" or \"Revised\" License", - ) - approvedPkgs = set.FromArray([]pkgInfo{ - // These packages are licensed under the LGPL, which is normally viral and hence - // incompatible with our licensing! However, they include the linking exception, - // allowing us to distribute a binary based on them as long as we don't modify them. - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/juju/ratelimit", - license: "GNU Lesser General Public License v3.0 (94%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/gopkg.in/yaml.v2", - license: "GNU Lesser General Public License v3.0 (95%)"}, - - // Licensed under Apache + some files with MIT/BSD style. - {pkgName: "github.com/projectcalico/calico/typha/vendor/gopkg.in/yaml.v2", - license: "? (The Unlicense, 35%)"}, - - // Variants on MIT/BSD; files tend to include updated copyright statement. - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/PuerkitoBio/urlesc", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/beorn7/perks/quantile", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/davecgh/go-spew/spew", - license: "ISC License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/dgrijalva/jwt-go", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/gogo/protobuf", - license: "BSD 3-clause \"New\" or \"Revised\" License (90%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/golang/protobuf", - license: "BSD 3-clause \"New\" or \"Revised\" License (92%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/golang/protobuf/proto", - license: "BSD 3-clause \"New\" or \"Revised\" License (92%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/gregjones/httpcache/diskcache", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/howeyc/gopass", - license: "ISC License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/imdario/mergo", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/kardianos/osext", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/kelseyhightower/envconfig", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/mailru/easyjson", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/pborman/uuid", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/peterbourgon/diskv", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/satori/go.uuid", - license: "MIT License (98%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/spf13/pflag", - license: "BSD 3-clause \"New\" or \"Revised\" License (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/google.golang.org/grpc", - license: "BSD 3-clause \"New\" or \"Revised\" License (97%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/gopkg.in/inf.v0", - license: "BSD 3-clause \"New\" or \"Revised\" License (97%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/dustin/go-humanize", - license: "MIT License (96%)"}, - - // Mixed license, Apache and some files under BSD-like. - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/ghodss/yaml", - license: "? (BSD 3-clause \"New\" or \"Revised\" License, 83%)"}, - - // Apache license with copyright statement in file. - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/Azure/go-autorest/autorest", - license: "Apache License 2.0 (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/gophercloud/gophercloud", - license: "Apache License 2.0 (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/vishvananda/netlink/nl", - license: "Apache License 2.0 (96%)"}, - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/vishvananda/netns", - license: "Apache License 2.0 (96%)"}, - - // Mozilla Public License. Note, would prohibit us from ever releasing our code - // under a *GPL license (if we wanted to do that). - {pkgName: "github.com/projectcalico/calico/typha/vendor/github.com/hashicorp/golang-lru/simplelru", - license: "Mozilla Public License 2.0"}, - }) - approvedPrefixes = []string{ - // Standard golang BSD-like license. - "github.com/projectcalico/calico/typha/vendor/golang.org/x/", - } -) - -func main() { - logutils.ConfigureEarlyLogging() - - wd, _ := os.Getwd() - log.WithField("PWD", wd).Info("Current directory") - file, err := os.Open("check-licenses/dependency-licenses.txt") // For read access. - if err != nil { - log.WithError(err).Panic("Failed to open licenses file") - } - scanner := bufio.NewScanner(file) - lineRE := regexp.MustCompile(`^(\S+)\s+(\S.*)$`) - badPackages := []pkgInfo{} -lineLoop: - for scanner.Scan() { - line := scanner.Text() - logCxt := log.WithField("line", line) - submatches := lineRE.FindStringSubmatch(line) - if len(submatches) != 3 { - logCxt.Panic("Expected line to match regex") - } - pkgName := submatches[1] - license := submatches[2] - logCxt = logCxt.WithFields(log.Fields{ - "pkgName": pkgName, - "license": license, - }) - logCxt.Debug("Found package") - pkgInfo := pkgInfo{ - pkgName: pkgName, - license: license, - } - if strings.HasPrefix(pkgName, "github.com/projectcalico/calico/typha/vendor/github.com/projectcalico/") || - (strings.HasPrefix(pkgName, "github.com/projectcalico/calico/") && - !strings.Contains(pkgName, "vendor")) { - logCxt.Info("One of our packages") - continue - } - if approvedLicenses.Contains(license) { - logCxt.Info("License is approved") - continue - } - if approvedPkgs.Contains(pkgInfo) { - logCxt.Info("Package is approved") - continue - } - for _, prefix := range approvedPrefixes { - if strings.HasPrefix(pkgName, prefix) { - logCxt.WithField("prefix", prefix).Info("Package prefix is approved") - continue lineLoop - } - } - logCxt.Error("License not approved") - badPackages = append(badPackages, pkgInfo) - } - - if len(badPackages) > 0 { - log.Error("Found bad licenses") - for _, pkg := range badPackages { - log.Errorf("\n\nNon-approved license:\n Package: %v\n License: %v\n", pkg.pkgName, pkg.license) - } - log.Info("") - os.Exit(1) - } -} - -type pkgInfo struct { - pkgName string - license string -} diff --git a/typha/pkg/daemon/daemon_test.go b/typha/pkg/daemon/daemon_test.go index 8b9a4f9decf..5fdcdf99977 100644 --- a/typha/pkg/daemon/daemon_test.go +++ b/typha/pkg/daemon/daemon_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018,2020 Tigera, Inc. All rights reserved. +// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -288,6 +288,11 @@ func (b *mockDatastore) EnsureInitialized(ctx context.Context, version, clusterT return nil } +// Tiers returns an interface for managing tier resources. +func (b *mockDatastore) Tiers() clientv3.TierInterface { + panic("not implemented") +} + // Nodes returns an interface for managing node resources. func (b *mockDatastore) Nodes() clientv3.NodeInterface { panic("not implemented") diff --git a/typha/pkg/logutils/logutils.go b/typha/pkg/logutils/logutils.go index 0b23e783293..5b90087c0c4 100644 --- a/typha/pkg/logutils/logutils.go +++ b/typha/pkg/logutils/logutils.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved. +// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import ( "os" "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" "github.com/projectcalico/calico/libcalico-go/lib/logutils" @@ -52,12 +53,8 @@ func ConfigureEarlyLogging() { // Log to stdout. This prevents fluentd, for example, from interpreting all our logs as errors by default. log.SetOutput(os.Stdout) - // Replace logrus' formatter with a custom one using our time format, - // shared with the Python code. - log.SetFormatter(&logutils.Formatter{}) - - // Install a hook that adds file/line no information. - log.AddHook(&logutils.ContextHook{}) + // Set up logging formatting. + logutils.ConfigureFormatter("typha") // First try the early-only environment variable. Since the normal // config processing doesn't know about that variable, normal config diff --git a/typha/utils/run-coverage b/typha/utils/run-coverage index 3aa7c1ce9ba..0ccf8a29e25 100755 --- a/typha/utils/run-coverage +++ b/typha/utils/run-coverage @@ -8,7 +8,7 @@ find . -name "*.coverprofile" -type f -delete echo "Calculating packages to cover..." go_dirs=$(find -type f -name '*.go' | \ - grep -vE '\./proto/|.glide|check-licenses|cmd/typha-client|\.go-pkg-cache' | \ + grep -vE '\./proto/|.glide|cmd/typha-client|\.go-pkg-cache' | \ xargs -n 1 dirname | \ sort | uniq | \ tr '\n' ',' | \